c++ - 将十六进制字符串转换为负 double

标签 c++ string visual-studio-2012

我正在尝试将十六进制字符串转换为 double 值,其中一些值为负数。 This answer对于正双十六进制字符串工作正常,但当双为负时,我得到一个 std::out_of_range 异常。这是为什么?有办法解决吗?

我也曾尝试用 stringstream 做同样的事情,这对正十六进制字符串和负十六进制字符串都适用。所以总有那个解决方案,但对我来说 union 方法看起来更优雅一些。我想这是一个品味问题。

示例代码:

#include <string>
#include <iostream>
#include <iomanip>
#include <sstream>


int main()
{
    std::string str1("3fb999999999999a"); //  0.1
    std::string str2("bfb999999999999a"); // -0.1


    // ******************************
    // UNION
    // ******************************
    union uint64double
    {
        unsigned long long i;
        double    d;
    };

    uint64double val1;
    val1.i = std::stoll(str1, nullptr, 16);

    uint64double val2;
    val2.i = std::stoll(str2, nullptr, 16);     // This throws std::out_of_range exception

    const int w = 18;

    std::cout << "USING UNION" << std::endl;
    std::cout << std::setw(w) << "HEX" << std::setw(w) << "DOUBLE" << std::endl;
    std::cout << std::setw(w) << str1 << std::setw(w) << val1.d << std::endl;
    std::cout << std::setw(w) << str2 << std::setw(w) << val2.d << std::endl;

    std::cout << std::endl;


    // ******************************
    // STRINGSTREAM
    // ******************************
    unsigned long long i1;
    std::stringstream ss;
    ss << std::hex << str1;
    ss >> i1;
    double d1(reinterpret_cast<double&>(i1));

    unsigned long long i2;
    ss.clear();
    ss << std::hex << str2;
    ss >> i2;
    double d2(reinterpret_cast<double&>(i2));

    std::cout << "USING STRINGSTREAM" << std::endl;
    std::cout << std::setw(w) << "HEX" << std::setw(w) << "DOUBLE" << std::endl;
    std::cout << std::setw(w) << str1 << std::setw(w) << d1 << std::endl;
    std::cout << std::setw(w) << str2 << std::setw(w) << d2 << std::endl;

    std::cout << std::endl;

    return 0;
}

输出:

USING UNION
           HEX            DOUBLE
  3fb999999999999a               0.1
  bfb999999999999a           1.#QNAN

USING STRINGSTREAM
               HEX            DOUBLE
  3fb999999999999a               0.1
  bfb999999999999a              -0.1

我正在使用 VS2012

最佳答案

当然stoll抛出 std::out_of_range exception输入 "bfb999999999999a" ,因为 0xbfb999999999999a > LLONG_MAX .如果你使用 stoull相反,一切都很好,因为 0xbfb999999999999a <= ULLONG_MAX .

关于c++ - 将十六进制字符串转换为负 double ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27387727/

相关文章:

c++ - 无法在 C++ 中创建包含日期和时间的文件名

javascript - 有没有一个函数可以用来检查两个字符串并返回nodejs中的常用单词/字母表

javascript - 使用 JavaScript 字符串操作剪切出精确的文本

c++ - 程序正在跳过 getline ()/C++

asp.net - 从带空格的文件夹进行 Web 部署

c++ - Visual Studio Express 2012 项目中忽略的环境变量

C++:指针与指针的指针在二叉树中插入节点

c++ - 为什么这个 EXC_BAD_ACCESS 发生在 long long 而不是 int 上?

c++ - 在运行时加载语法

c++ - 递归尾随返回类型的名称解析