【问题标题】:LDBL_MAX: Why does long double value print so many digits?LDBL_MAX:为什么 long double value 打印这么多数字?
【发布时间】:2021-01-13 22:03:12
【问题描述】:
printf("Unit \"long double\" -> %i bytes -> range %Lf - %Lf.\n",\
                        sizeof(long double), LDBL_MIN, LDBL_MAX);

返回

单位 "long double" -> 16 字节 -> 范围 0.000000 - 1189731495357231765021263853030970205169063322294624200440323733891737005522970722616410290336528882853545697807495577314427443153670288434198125573853743678673593200706973263201915918282961524365529510646791086614311790632169778838896134786560600399148753433211454911160088679845154866512852340149773037600009125479393966223151383622417838542743917838138717805889487540575168226347659235576974805113725649020884855222494791399377585026011773549180099796226026859508558883608159846900235645132346594476384939859276456284579661772930407806609229102715046085388087959327781622986827547830768080040150694942303411728957777100335714010559775242124057347007386251660110828379119623008469277200965153500208474470792443848545912886723000619085126472111951361467527633519562927597957250278002980795904193139603021470997035276467445530922022679656280991498232083329641241038509239184734786121921697210543484287048353408113042573002216421348917347174234800714880751002064390517234247656004721768096486107994943 4157034763206435586242074435044243805661360176088374781653890278095769759772868600714870282879555671414046326158326236027628963161739784842544868606099482708679680480787025118589308385465842230409088059962945945862019037660484467909260022254105307759010657606713472001258464069570302571389609837579989269545530523685607586831792231136395194688508807718721047052039575874800131431314442549439199401757531693393923668818561891299317291042529212368351599223220509980016771027840353601408292963981151228777681357060457893435354516965395612540488464471697868932116710872290880827783505182288576460622187397028516550837209923494833344352289847512327537266360662139022812647062340753520717240586650795182173034637826313533937067749019501978416904418247380631628285868577414325811653640402184027249133933209492194984224427304270198730445366203502623869578046820036014472919971230955300572061418669748528468561865148327159744812031219467516863793430961896151073300655524214851952017628585950910518394725028638 7163249416761380499631979144187025430270675849519200883791516940158174004671147787720145964446117520405945350476472180797576111172084627363927960033967047003761337450955318415007379641260504792325166135484129188421134082301547330475406707281876350361733290800595189632520707167390454777712968226520622565143991937680440029238090311243791261477625596469422198137514696707944687035800439250765945161837981185939204954403611491531078225107269148697980924094677214272701240437718740921675661363493890045123235166814608932240069799317601780533819184998193300841098599393876029260139091141452600372028487213241195542428210183120421610446740462163533690058366460659115629876474552506814500393294140413149540067760295100596225302282300363147382468105964844244132486457313743759509641616804802412935187620466813563687753281467553879887177183651289394719533506188500326760735438867336800207438784965701457609034985757124304510203873049485425670247933932280911052604153852899484920399109194612991249163328991799 8094380337879522093131466946149705939664152375949285890960489916121944989986384837022486672249148924678410206183364627416969576307632480235587975245253737035433882960862753427740016333434055083537048507374544819754722228975281083020898682633020285259923084168054539687911418297629988964576482765287504562854924265165217750799516259669229114977788962356670956627138482018191348321687995863652637620978285070099337294396784639879024914514222742527006363942327998483976739987154418554201562244154926653014515504685489258620276085761837129763358761215382565129633538141663949516556000264159186554850057052611431952919918807954522394649627635630178580896692226406235382898535867595990647008385687123810329591926494846250768992258419305480763620215089022149220528069842018350840586938493815498909445461977893029113576516775406232278298314033473276603952231603422824717528181818844304880921321933550869873395861276073670866652375555675803171490108477320096424318780070008797346032906278943553743564448851907 191616455141155761939399690767415156402826543664026760095087523945507341556135867933066031744720924446513532366647649735400851967040771103640538150073486891798364049570606189535005089840913826869535090066783324472578712196604415284924840041850932811908963634175739897166596000759487800619164094854338758520657116541072260996288150123144377944008749301944744330784388995701842710004808305012177123560622895076269042856800047718893158089358515593863176652948089031267747029662545110861548958395087796755464137944895960527975209874813839762578592105756284401759349324162148339565350189196811389091843795734703269406342890087805846940352453479398080674273236297887100867175802531561302356064878709259865288416350972529537091114317204887747405539054009425375424119317944175137064689643861517718849867010341532542385911089624710885385808688837777258648564145934262121086647588489260031762345960769508849149662444156604419552086811989770240.000000 P>

也许这是一个愚蠢的问题,但这真的是long double 可以容纳的最大值吗? (绝对的规模让我大吃一惊)。也许我犯了一些愚蠢的错误,而 C 向我抛出了一个垃圾值?

我在 Linux 上使用 64 位 gcc 编译代码。

【问题讨论】:

  • 我已删除您的后续问题,因为它与您的问题并不真正相关,并且可能会使对话偏离猜测。
  • @user694733 没问题,无论如何我应该在一个单独的问题中询问 long float 。谢谢!
  • @pmg:不,不是,所有的数字都是正确的。只要 C 实现使用正确的二进制-十进制和十进制-二进制转换,就没有理由将它们产生的数字视为垃圾。
  • 这是一个仅仅欣赏 64 位计算潜力的问题吗?

标签: c types floating-point double long-integer


【解决方案1】:

这个page可以帮你搞清楚

float 是 32 位大小或 4 个字节 没有长浮点数,浮点数的替代名称是 Single 在其他语言(如 C#)中 double 的大小为 8 个字节,long double 的大小为 16 个字节

对于打印值,您可以使用此代码

printf("%f", _float_var);
printf("%lf", _double_var);
printf("%Lf", _long_double_var);

这个page 描述了双倍存储多长时间以及如何自己计算最小值和最大值以确保

一些可以存储在 long double 中的值

2−16382 × 2−112 = 2−16494
≈ 6.4751751194380251109244389582276465525 × 10−4966
                                            (smallest positive subnormal number)
2−16382 × (1 − 2−112)
≈ 3.3621031431120935062626778173217519551 × 10−4932
                                            (largest subnormal number)
2−16382
≈ 3.3621031431120935062626778173217526026 × 10−4932
                                            (smallest positive normal number)
216383 × (2 − 2−112)
≈ 1.1897314953572317650857593266280070162 × 104932
                                            (largest normal number)
= 1 − 2−113
≈ 0.9999999999999999999999999999999999037
                                            (largest number less than one)
1 + 2−112
≈ 1.0000000000000000000000000000000001926
                                            (smallest number larger than one)

【讨论】:

  • 请注意,printf() 转换说明符 "%f""%lf" 100% 完全相同(自 C99 以来;"%lf" 未在 C90 中描述)。原型中没有... 的函数采用float 值,因为在调用函数之前它们会自动转换为double 类型。
  • 是的 printf 是基于你使用的系统和编译器我更喜欢使用我自己的函数将浮点数、双精度数或其他类型转换为字符串然后打印它们
  • 您的链接显示了 一个 的可能性 double 可以存储多长时间,目前很少使用,并且在大多数架构上都没有硬件支持。
【解决方案2】:

long double 有三种常见的实现方式: 1. 无聊的 long double 与 double 相同。 2. IEEE 754 中的 long double 存储有 15 位指数和 64 位尾数。 3. 一个有趣的结果,其中 long double 存储为与两个 double 数字 x + y 相同的值,其属性为 round (x + y) = x。

在第一种和第三种情况下,long double 通常有大约 308 位,就像 double 一样。在第二种情况下,long double 能够容纳超过 4,900 个数字。

【讨论】:

  • 在哪里可以了解更多关于这些不同的常见实现的信息?
  • 第一个很明显。 “ieee 754”或“扩展精度”的第二个谷歌。第三个找IBM的PowerPC/POWER架构文档;这是 Mac 在 2006 年左右从 PowerPC 切换到 Intel 处理器之前使用的方法。
  • @computronium 还阅读了 Paul Zimmermann 的书中关于大数算术的内容/
  • @alinsoar 哪一个?有几种。他们似乎都与足球有关!
【解决方案3】:

这个数字正好是 216,384−216,320。 (打印正确;我检查了所有数字。)它是 IEEE-754 方案中使用 15 位指数和 64 位有效数可表示的最大有限值:

  • 对于 15 位,指数范围为 -16,382 到 +16,383。
  • 对于 64 位,有效数字的最大值(按 [1, 2) 正常范围缩放)为 20+2−1+2−2+…+2−63 = 2−2−63.
  • 所以最大的有限值为+(2−2−63)•216,383 = 216,384−216,320 .

这与 Intel 的 80 位浮点格式相匹配。您可以通过包含<float.h> 并打印FLT_RADIX(应为2)、LDBL_MANT_DIG (64)、LDBL_MIN_EXP (−16,381) 和LDBL_MAX_EXP (16,384) 的值来确认。 (C 指数与 IEEE-754 指数相差 1,因为 C 在 [½, 1) 正常范围内缩放有效位。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-11
    相关资源
    最近更新 更多