多长的 double 可以在 12 个字节中容纳这么多字符?

Posted

技术标签:

【中文标题】多长的 double 可以在 12 个字节中容纳这么多字符?【英文标题】:How long double fits so many characters in just 12 bytes? 【发布时间】:2019-07-23 20:14:52 【问题描述】:

double 能在 12 个字节中容纳这么多字符需要多长时间?

我做了一个例子,一个 C++ 阶乘 当输入一个大数字时,例如 1754,它会使用一个显然不适合 long double 类型的数字进行计算。

#include <iostream>
#include <string.h>

using namespace std;
int main()

    unsigned int n;
    long double fatorial = 1;
    cout << "Enter number: ";
    cin >> n;
    for(int i = 1; i <=n; ++i)
    
        fatorial *= i;
    

    string s = to_string(fatorial);
    cout << "Factorial of " << n << " = " <<fatorial << " = " << s;
    return 0;

重要提示: Windows 上的 GCC 编译器,由 visual Studio long double 表现得像一个 double

问题是怎么存储的还是to_string函数?

【问题讨论】:

请注意,结果并不完全准确,因为任何至少为 5 的整数的阶乘必须以零结尾。 可能是重复的? ***.com/q/2706851/1896169 long double 似乎是错误的数据类型.. 用很少的数字写一个大数字很容易。 2 的 1000 次方,是一个非常大的数字,大约有 300 位数字,但我只用五位数字写了它。嗯,这正是 double 的长度。 How are floating point numbers are stored in memory?的可能重复 【参考方案1】:

std::to_string(factorial) 将返回一个包含与std::sprintf(buf, "%Lf", value) 相同结果的字符串。

反过来,%Lf 打印long double 的整个整数部分、一个句点和小数部分的 6 位小数。

由于factorial 是一个非常大的数字,你最终会得到一个非常长的字符串。

但是,请注意这与long double 无关。一个更简单的例子,例如double 是:

#include <iostream>
#include <string>

int main()

    std::cout << std::to_string(1e300) << '\n';
    return 0;

这将打印:

10000000000000000525047602 [...300 decimal digits...] 540160.000000

十进制数字不完全为零,因为该数字不完全是1e300,而是最接近可以用浮点类型表示的数字。

【讨论】:

这个例子很好,简单明了,但是这个特性是因为正确的to_string吗? @Dorathoto 您具体指的是什么功能? 在 1e300 中不仅是零(应该有 300 个零) @Dorathoto 不,这是该语言的一个特点。当您使用文字时,编译器将使用(其中一个)可以在给定类型中表示的最接近的值,因为您不能将 1e300 完全存储在 double 中。所以你最终得到另一个值(它有非零数字)。然后使用该值调用std::to_string @jxh 不,不能准确存储。有一些算法可以近似十进制表示,但这不是这里的问题。【参考方案2】:

它不适合那么多字符。相反,to_string 从数据中生成了那么多字符。

这是一个玩具程序:

std::string my_to_string( bool b ) 
  if (b)
    return "This is a string that never ends, it goes on and on my friend, some people started typing it not knowing what it was, and now they still are typing it it just because this is the string that never ends, it goes on and on my friend, some people started typing it not knowing what it was, and now they still are typing it just because...";
  else
    return "no it isn't, I can see the end right ^ there";

bool 恰好存储 1 位数据。但是它通过调用my_to_string 生成的字符串可以任意长。

doubleto_string就是这样。它生成的字符远远多于double 中的“信息”。

这是因为它在输出时被编码为以 10 为底的数字。在double内部,它被编码为无符号数、符号位和指数部分的组合。

“值”大致为“1+数字/2^常数”,符号乘以+/- 1,乘以“2^指数部分”。

base 2 中只有一定数量的“精度位”;如果您以 2 为底(或十六进制,或任何 2 的幂次方)打印它,则双精度数将有几个非零数字,然后是一堆 0(或者,如果很小,它将有 0.0000 ... 000 然后是几个非零数字)。

但是当转换为以 10 为底时,其中没有一堆零数字。

取 0b10000000 -- 也就是 2^8。这是以 10 为底的 256 - 它根本没有尾随 0!

【讨论】:

【参考方案3】:

这是因为浮点数只存储实际值的近似值。如果您查看the actual exact value of 1754!,您会发现您的结果在前~18 位数字之后变得完全不同。之后的数字只是以十进制写入(的倍数)二的大幂的结果。

【讨论】:

以上是关于多长的 double 可以在 12 个字节中容纳这么多字符?的主要内容,如果未能解决你的问题,请参考以下文章

C语言中 int 类型在内存中占4个字节 double类型在内存中占8个字节 为啥地址编译出来都是6个16进制数字

base64url编码后的24bytes有多长

字节大小(说明)

浮点类型说明浮float,double有啥区别啊

windows 编程 —— 宽字符集 与 Unicode

c语言中啥算是实型数据?举例子!