为了清晰和简单起见,我将将以下数字缩短如下:
−170,141,183,460,469,231,731,687,303,715,884,105,728 as -170…728170,141,183,460,469,231,731,687,303,715,884,105,727 as 170…727这些数字表示128位有符号整数(__int128 in gcc)的最小值和最大值.
我为这种数据类型实现了用户定义的文本(原始文本),因为gcc没有提供一种方法来定义这种类型的常量:_u128表示unsigned __int128,_i128表示__int128。
减号字符不是UDL的一部分,而是应用于UDL结果的一元减号运算符。
因此,对于一个-ddddd_i128 (其中d是一个数字),UDL用正值ddddd计算签名的 __int128,然后编译器将对其应用一元减号运算符。到目前一切尚好。
问题在于-170…128_i128 (它应该是__int128的有效值):
UDL计算有符号的 __int128正数170…128,它刚好超出__int128的范围,导致未定义的行为(有符号整数溢出)。
用UDL表示这个数常量的解决方案是什么?
我的UDL被声明了(暂时只是一个非参数的,头晕的版本)(它们是原始的文字):
unsigned __int128 operator"" _u128(char const *str);
__int128 operator"" _i128(char const *str);一些用法:
1000000000000000000000000000000000_i128
-1000000000000000000000000000000000_i128
-170141183460469231731687303715884105728_i128 // <-- this has UB
170141183460469231731687303715884105727_u128
340282366920938463463374607431768211455_u128我知道有多种方法来定义常量-170…728,比如位移位、数学运算,但我希望能够以一致的方式创建它,例如,我不希望出现这种情况:您可以使用这个UDL创建任何常量,除了-170…728_i128,您必须使用额外的技巧。
发布于 2014-08-05 18:59:43
这与实现者在实现<limits.h>时遇到的问题本质上是一样的:INT_MIN不能定义为-2147483648 (在典型的32位系统上)。它可以(而且通常是)定义为(-2147483647 - 1)。你得做些类似的事。可能没有任何方法用一个否定运算符和文字来表示最负的数字,但没关系:根本不需要它。
https://stackoverflow.com/questions/25143372
复制相似问题