C++ - 将 long 转换为 float 或双舍入值

C++ - Converting long to float or double rounds the value

我想将 long 转换为 float/double 但对值进行四舍五入。如何在不四舍五入的情况下进行转换?

这是我的代码:

#include <cmath>
#include <iostream>

int main()
{
    const uint32_t UW = 1000;
    int txPower = 3012916;

    long x = std::stoi("3012916") * UW;
    std::cout << "x = " << x << std::endl;

    auto xFloat = (float)x;
    std::cout << "x float = " << xFloat << std::endl;

    auto xDouble = (double)x;
    std::cout << "xDouble = " << xDouble << std::endl;
    std::cout << "xDouble value cast = " << (double)3012916000 << std::endl;

    return 0;
}

产生这个输出:

x = 3012916000                                                                                                                                              
x float = 3.01292e+09                                                                                                                                       
xDouble = 3.01292e+09                                                                                                                                       
xDouble value cast = 3.01292e+09

求助!

"How can I convert without it being rounded?" 由于其技术表示形式,将整数值表示为浮点值总是对其进行四舍五入。 看这里 Convert int to double

正如 Mark Ransom 在评论中提到的那样,您看到的输出只是存储在 float 或 [=33 中的实际值的缩写形式=]双值。您可以使用 std::setprecision(15).

查看更多数字

标准的单精度浮点值有 32 位,其中 23 位保留给尾数。当浮点值不为零时,尾数的最高有效位被假定为 1(但不存储)。这意味着您有 24 位用于存储,尾数可以容纳的最大值是 2^24 或 16777216。如您所见,您可以存储大约 7 位数字而不会丢失精度。我说 'about' 是因为并非所有浮点值的十进制表示都可以用二进制格式以相同的精度表示。

这是一个有趣的实验:

long n0 = 16777210;
for (int i = 0; i < 10; i++)
{
    long n = n0 + i;
    std::cout << "n=" << n << " / ((float)n)=" << std::setprecision(15) << ((float)n) << std::endl;
}

输出为:

n=16777210 / ((float)n)=16777210
n=16777211 / ((float)n)=16777211
n=16777212 / ((float)n)=16777212
n=16777213 / ((float)n)=16777213
n=16777214 / ((float)n)=16777214
n=16777215 / ((float)n)=16777215
n=16777216 / ((float)n)=16777216
n=16777217 / ((float)n)=16777216
n=16777218 / ((float)n)=16777218
n=16777219 / ((float)n)=16777220

数字 3012916000 太大,无法精确保存在单精度浮点值中。当你像这样输出你的数字时:

std::cout << "x float = " << std::setprecision(15) << xFloat << std::endl;

则输出为:

x float = 3012915968

双精度值有 52+1 位尾数,因此您的数字可以准确存储:

std::cout << "xDouble = " << std::setprecision(15) << xDouble << std::endl;

输出:

xDouble = 3012916000