可以存储在 long double 中的最大整数
Largest integer that can be stored in long double
编辑:在评论中进行了一些讨论后发现,由于幸运地了解如何在 C 中实现浮点数,我问了一些与我想问的不同的问题。
我想使用(进行操作)大于我可以使用 unsigned long long
的整数(对我来说是 8 个字节),可能不会重复出现在数组或 bigint 库中。由于我的 long double
是 16 个字节,我认为只要切换类型就可以实现。事实证明,即使可以表示更大的整数,您也无法在不损失精度的情况下使用这些更大的 long double
整数进行运算。所以不可能实现我想做的事情。实际上,正如评论中所述,这对我来说是不可能的。但总的来说,是否可能取决于你的 long double
.
的浮点特性
// end of EDIT
我想了解我可以存储在 long double
中的最大整数是多少。
我知道这取决于程序内置的环境,但我不知道具体如何。我有一个 sizeof(long double) == 16
的价值。
现在 this answer 他们说 64 位双精度数的最大值应该是 2^53,大约是 9 x 10^15,正好是 9007199254740992
.
当我 运行 以下程序时,它正常工作:
#include <stdio.h>
int main() {
long double d = 9007199254740992.0L, i;
printf("%Lf\n", d);
for(i = -3.0; i < 4.0; i++) {
printf("%.Lf) %.1Lf\n", i, d+i);
}
return 0;
}
它甚至与 11119007199254740992.0L
一起工作,它是在开头添加四个 1
的相同数字。但是,当我再添加一个 1
时,第一个 printf
按预期工作,而所有其他的显示第一个打印的相同数量。
所以我试图用这个程序
获得我的long double
的最大值
#include <stdio.h>
#include <math.h>
int main() {
long double d = 11119007199254740992.0L, i;
for(i = 0.0L; d+i == d+i-1.0; i++) {
if( !fmodl(i, 10000.0L) ) printf("%Lf\n", i);
}
printf("%.Lf\n", i);
return 0;
}
但它打印 0
.
(编辑:我刚刚意识到我需要 for
中的条件 !=
)
总是在同一个答案中,他们说 double 的最大可能值为 DBL_MAX
或大约 1.8 x 10^308。
我不知道这是什么意思,但如果我 运行
printf("%e\n", LDBL_MAX);
我每次都得到一个不同的值,它总是在 6.9 x 10^(-310) 左右。
(编辑:我应该使用 %Le
,输出值约为 1.19 x 10^4932)
我从 here.
中提取了 LDBL_MAX
这个我也试过了
printf("%d\n", LDBL_MAX_10_EXP);
这给出了值 4932
(我也在 C++ 问题中找到了)。
因为我们有 16 个字节用于 long double
,即使它们都是类型的整数部分,我们也可以存储数字直到 2^128,即大约 3.4 x 10 ^38。所以我不明白 308、-310 和 4932 应该是什么意思。
有人能告诉我如何找出可以存储为 long double
的最大整数吗?
您可以使用limits.h
在您的机器上打印最大值,值为ULLONG_MAX
在 https://www.geeksforgeeks.org/climits-limits-h-cc/ 中是一个 C++ 示例。
使用 printf() 打印 unsigned long long 的格式说明符是 %llu
打印 long double 它是 %Lf
printf("unsigned long long int: %llu ",(unsigned long long) ULLONG_MAX);
printf("long double: %Lf ",(long double) LDBL_MAX);
https://www.tutorialspoint.com/format-specifiers-in-c
也在Printing unsigned long long int Value Type Returns Strange Results
假设您的意思是“在不丢失信息的情况下存储”,LDBL_MANT_DIG
gives the number of bits used for the floating-point mantissa,那么这就是在不丢失信息的情况下可以存储的整数值的位数。*
您需要 128 位整数来轻松确定 128 位浮点数中可以容纳的最大整数值,但这至少会发出十六进制值(假设 unsigned long long
是 64位 - 您可以使用 CHAR_BIT
和 sizeof( unsigned long long )
来获得可移植的答案):
#include <stdio.h>
#include <float.h>
#include <limits.h>
int main( int argc, char **argv )
{
int tooBig = 0;
unsigned long long shift = LDBL_MANT_DIG;
if ( shift >= 64 )
{
tooBig = 1;
shift -= 64;
}
unsigned long long max = ( 1ULL << shift ) - 1ULL;
printf( "Max integer value: 0x" );
// don't emit an extraneous zero if LDBL_MANT_DIG is
// exactly 64
if ( max )
{
printf( "%llx", max );
}
if ( tooBig )
{
printf( "%llx", ULLONG_MAX );
}
printf( "\n" );
return( 0 );
}
* - 迂腐地,它是 FLT_RADIX
基数中的位数,但该基数几乎可以肯定是 2.
鉴于您在评论中表示要使用 long double
代替 long long
以获得更大的范围,我假设您还需要单位精度。因此,您要求的是浮点表示法 (FLT_RADIX
) 基数中可用尾数位数 (LDBL_MANT_DIG
) 可表示的最大数。在 非常 可能的事件 FLT_RADIX == 2
中,您可以像这样计算该值:
#include <float.h>
#include <math.h>
long double get_max_integer_equivalent() {
long double max_bit = ldexpl(1, LDBL_MANT_DIG - 1);
return max_bit + (max_bit - 1);
}
ldexp
系列函数按 2 的幂缩放浮点值,类似于移位运算符(<<
和 >>
)对整数所做的操作,因此以上类似于
// not reliable for the purpose!
unsigned long long max_bit = 1ULL << (DBL_MANT_DIG - 1);
return max_bit + (max_bit - 1);
尽管您假设 long double
提供的尾数位数比 long long
的值位多,但是,您必须假设位移会溢出。
当然,您的 long double
可以表达更大的值,它们都是整数。但是它们没有单位精度,因此当 long double
的值较大时,您的 long double
的行为将与整数的预期行为不同。例如,如果 long double
变量 d
包含一个更大的值,那么 d + 1 == d
和 d - 1 == d
中的至少一个可能计算为真。
编辑:在评论中进行了一些讨论后发现,由于幸运地了解如何在 C 中实现浮点数,我问了一些与我想问的不同的问题。
我想使用(进行操作)大于我可以使用 unsigned long long
的整数(对我来说是 8 个字节),可能不会重复出现在数组或 bigint 库中。由于我的 long double
是 16 个字节,我认为只要切换类型就可以实现。事实证明,即使可以表示更大的整数,您也无法在不损失精度的情况下使用这些更大的 long double
整数进行运算。所以不可能实现我想做的事情。实际上,正如评论中所述,这对我来说是不可能的。但总的来说,是否可能取决于你的 long double
.
// end of EDIT
我想了解我可以存储在 long double
中的最大整数是多少。
我知道这取决于程序内置的环境,但我不知道具体如何。我有一个 sizeof(long double) == 16
的价值。
现在 this answer 他们说 64 位双精度数的最大值应该是 2^53,大约是 9 x 10^15,正好是 9007199254740992
.
当我 运行 以下程序时,它正常工作:
#include <stdio.h>
int main() {
long double d = 9007199254740992.0L, i;
printf("%Lf\n", d);
for(i = -3.0; i < 4.0; i++) {
printf("%.Lf) %.1Lf\n", i, d+i);
}
return 0;
}
它甚至与 11119007199254740992.0L
一起工作,它是在开头添加四个 1
的相同数字。但是,当我再添加一个 1
时,第一个 printf
按预期工作,而所有其他的显示第一个打印的相同数量。
所以我试图用这个程序
long double
的最大值
#include <stdio.h>
#include <math.h>
int main() {
long double d = 11119007199254740992.0L, i;
for(i = 0.0L; d+i == d+i-1.0; i++) {
if( !fmodl(i, 10000.0L) ) printf("%Lf\n", i);
}
printf("%.Lf\n", i);
return 0;
}
但它打印 0
.
(编辑:我刚刚意识到我需要 for
中的条件 !=
)
总是在同一个答案中,他们说 double 的最大可能值为 DBL_MAX
或大约 1.8 x 10^308。
我不知道这是什么意思,但如果我 运行
printf("%e\n", LDBL_MAX);
我每次都得到一个不同的值,它总是在 6.9 x 10^(-310) 左右。
(编辑:我应该使用 %Le
,输出值约为 1.19 x 10^4932)
我从 here.
LDBL_MAX
这个我也试过了
printf("%d\n", LDBL_MAX_10_EXP);
这给出了值 4932
(我也在
因为我们有 16 个字节用于 long double
,即使它们都是类型的整数部分,我们也可以存储数字直到 2^128,即大约 3.4 x 10 ^38。所以我不明白 308、-310 和 4932 应该是什么意思。
有人能告诉我如何找出可以存储为 long double
的最大整数吗?
您可以使用limits.h
在您的机器上打印最大值,值为ULLONG_MAX
在 https://www.geeksforgeeks.org/climits-limits-h-cc/ 中是一个 C++ 示例。
使用 printf() 打印 unsigned long long 的格式说明符是 %llu
打印 long double 它是 %Lf
printf("unsigned long long int: %llu ",(unsigned long long) ULLONG_MAX);
printf("long double: %Lf ",(long double) LDBL_MAX);
https://www.tutorialspoint.com/format-specifiers-in-c
也在Printing unsigned long long int Value Type Returns Strange Results
假设您的意思是“在不丢失信息的情况下存储”,LDBL_MANT_DIG
gives the number of bits used for the floating-point mantissa,那么这就是在不丢失信息的情况下可以存储的整数值的位数。*
您需要 128 位整数来轻松确定 128 位浮点数中可以容纳的最大整数值,但这至少会发出十六进制值(假设 unsigned long long
是 64位 - 您可以使用 CHAR_BIT
和 sizeof( unsigned long long )
来获得可移植的答案):
#include <stdio.h>
#include <float.h>
#include <limits.h>
int main( int argc, char **argv )
{
int tooBig = 0;
unsigned long long shift = LDBL_MANT_DIG;
if ( shift >= 64 )
{
tooBig = 1;
shift -= 64;
}
unsigned long long max = ( 1ULL << shift ) - 1ULL;
printf( "Max integer value: 0x" );
// don't emit an extraneous zero if LDBL_MANT_DIG is
// exactly 64
if ( max )
{
printf( "%llx", max );
}
if ( tooBig )
{
printf( "%llx", ULLONG_MAX );
}
printf( "\n" );
return( 0 );
}
* - 迂腐地,它是 FLT_RADIX
基数中的位数,但该基数几乎可以肯定是 2.
鉴于您在评论中表示要使用 long double
代替 long long
以获得更大的范围,我假设您还需要单位精度。因此,您要求的是浮点表示法 (FLT_RADIX
) 基数中可用尾数位数 (LDBL_MANT_DIG
) 可表示的最大数。在 非常 可能的事件 FLT_RADIX == 2
中,您可以像这样计算该值:
#include <float.h>
#include <math.h>
long double get_max_integer_equivalent() {
long double max_bit = ldexpl(1, LDBL_MANT_DIG - 1);
return max_bit + (max_bit - 1);
}
ldexp
系列函数按 2 的幂缩放浮点值,类似于移位运算符(<<
和 >>
)对整数所做的操作,因此以上类似于
// not reliable for the purpose!
unsigned long long max_bit = 1ULL << (DBL_MANT_DIG - 1);
return max_bit + (max_bit - 1);
尽管您假设 long double
提供的尾数位数比 long long
的值位多,但是,您必须假设位移会溢出。
当然,您的 long double
可以表达更大的值,它们都是整数。但是它们没有单位精度,因此当 long double
的值较大时,您的 long double
的行为将与整数的预期行为不同。例如,如果 long double
变量 d
包含一个更大的值,那么 d + 1 == d
和 d - 1 == d
中的至少一个可能计算为真。