然而,没有答案能够以编程方式找到/证明这一点(除了一个CoolAJ86在his answer中提到的将在28 . 56年内完成;),所以这里's a slightly more efficient way to do that (to be precise, it'更有效率约28.559999999968312年:),以及test fiddle:
/**
* Checks if adding/subtracting one to/from a number yields the correct result.
*
* @param number The number to test
* @return true if you can add/subtract 1, false otherwise.
*/
var canAddSubtractOneFromNumber = function(number) {
var numMinusOne = number - 1;
var numPlusOne = number + 1;
return ((number - numMinusOne) === 1) && ((number - numPlusOne) === -1);
}
//Find the highest number
var highestNumber = 3; //Start with an integer 1 or higher
//Get a number higher than the valid integer range
while (canAddSubtractOneFromNumber(highestNumber)) {
highestNumber *= 2;
}
//Find the lowest number you can't add/subtract 1 from
var numToSubtract = highestNumber / 4;
while (numToSubtract >= 1) {
while (!canAddSubtractOneFromNumber(highestNumber - numToSubtract)) {
highestNumber = highestNumber - numToSubtract;
}
numToSubtract /= 2;
}
//And there was much rejoicing. Yay.
console.log('HighestNumber = ' + highestNumber);
input: 2251799813685246.75 output: 2251799813685246.8 // expected: 2251799813685246.75
input: 2251799813685246.25 output: 2251799813685246.2 // expected: 2251799813685246.25
input: 2251799813685246.5 output: 2251799813685246.5
// If the digits exceed 17, JavaScript round it to print it.
//, but the value is held correctly:
input: 2251799813685246.25.toString(2)
output: "111111111111111111111111111111111111111111111111110.01"
input: 2251799813685246.75.toString(2)
output: "111111111111111111111111111111111111111111111111110.11"
input: 2251799813685246.78.toString(2)
output: "111111111111111111111111111111111111111111111111110.11"
exponent part 的可用范围是多少?格式为它分配了11位 . Wiki的完整格式:(详情请到那里)
var x = 9007199254740992;
var y = -x;
x == x + 1; // true !
y == y - 1; // also true !
// Arithmetic operators work, but bitwise/shifts only operate on int32:
x / 2; // 4503599627370496
x >> 1; // 0
x | 1; // 1
21 回答
在JavaScript中,有一个名为
Infinity
的数字 .例子:
对于有关此主题的一些问题,这可能就足够了 .
Node.js和Google Chrome似乎都使用1024位浮点值,因此:
Jimmy's answer正确表示连续的JavaScript整数频谱为 -9007199254740992 至 9007199254740992 包含(对不起9007199254740993,您可能认为您是9007199254740993,但您错了!演示如下或在jsfiddle中) .
然而,没有答案能够以编程方式找到/证明这一点(除了一个CoolAJ86在his answer中提到的将在28 . 56年内完成;),所以这里's a slightly more efficient way to do that (to be precise, it'更有效率约28.559999999968312年:),以及test fiddle:
之前的许多答案都显示
9007199254740992 === 9007199254740992 + 1
的结果true
告诉 9 007 199 254 740 991 是最大安全整数 .
如果我们继续积累怎么办:
我们可以发现,在大于 9 007 199 254 740 992 的数字中,只有偶数是 representable .
这是一个解释 double-precision 64-bit binary format 如何解决这个问题的条目 . 让我们看看如何使用这种二进制格式保持(表示) 9 007 199 254 740 992 .
我们从 4 503 599 627 370 496 开始,首先是格式的简短版本:
在箭头的左侧,我们有 bit value 1 ,并且相邻 radix point ,然后通过乘以
2^52
,我们向右移动基点52步,并且它到达结尾 . 现在我们得到二进制4503599627370496 .现在我们开始累积1到这个值,直到所有位都设置为1,等于 9 007 199 254 740 991 十进制 .
现在,因为在 double-precision 64-bit binary format 中,它严格地为分数分配52位,没有更多的位可用于添加一个1,所以我们可以做的是将所有位设置回0,并操纵指数部分:
现在我们得到 9 007 199 254 740 992 ,并且数字大于它,格式可以容纳的是 2 times of the fraction :
因此,当数字大于9 007 199 254 740 992 * 2 = 18 014 398 509 481 984时,只能持有 4 times of the fraction :
[ 2 251 799 813 685 248 , 4 503 599 627 370 496 ]之间的数字怎么样?
小数点后的位值1精确为2 ^ -1 . (= 1/2,= 0.5)因此,当数字小于 4 503 599 627 370 496 (2 ^ 52)时,有一位可用于表示 1/2 times of the integer :
小于 2 251 799 813 685 248 (2 ^ 51)
exponent part 的可用范围是多少?格式为它分配了11位 . Wiki的完整格式:(详情请到那里)
因此,要在指数部分获得2 ^ 52,我们需要设置e = 1075 .
我用公式做了一个简单的测试,X-(X 1)= - 1,X的最大值可以在Safari上运行,Opera和Firefox(在OS X上测试)是9e15 . 这是我用于测试的代码:
>= ES6:
Number.MIN_SAFE_INTEGER; Number.MAX_SAFE_INTEGER;
<= ES5
来自the reference:
Number.MAX_VALUE; Number.MIN_VALUE;
它是253 == 9 007 199 254 740 992.这是因为
Number
被存储为52位尾数中的浮点数 .最小值为-253 .
这会让一些有趣的事情发生
而且也可能是危险的:)
进一步阅读:http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html
为了安全起见
推理
我以为我会聪明,并且用更务实的方法找到
x + 1 === x
的 Value .我的机器每秒只能计算1000万左右......所以我会在28 . 56年内回复最终答案 .
如果你不能等那么久,我愿意打赌
你的大多数循环都没有运行28 . 56年
9007199254740992 === Math.pow(2, 53) + 1
就足够了你应该坚持
4294967295
这是Math.pow(2,32) - 1
,以避免比特移位的预期问题找到
x + 1 === x
:尝试:
在Firefox 3.6中它是2 ^ 31 - 1 .
+/- 9007199254740991
ECMA Section 8.5 - Numbers
它们是64位浮点值,最大精确积分值是253-1或
9007199254740991
. 在ES6中,这被定义为Number.MAX_SAFE_INTEGER .请注意,按位运算符和移位运算符以32位整数运算,因此在这种情况下,最大安全整数为231-1或2147483647 .
测试出来!
有关数字9007199254740992的技术说明:该值有一个精确的IEEE-754表示,您可以从变量中分配和读取该值,因此对于小于或等于整数域的非常仔细选择的应用程序此值,您可以将其视为最大值 .
在一般情况下,您必须将此IEEE-754值视为不精确,因为它是否对其进行编码是不明确的逻辑值9007199254740992或9007199254740993 .
ECMAScript 6:
我这样写:
对于int32也是如此
让我们来看看消息来源
说明
浏览器兼容性
Firefox 3似乎没有大数字的问题 .
1e 200 * 1e 100将计算罚款1e 300 .
Safari似乎也没有问题 . (据记录,如果其他人决定对此进行测试,这是在Mac上 . )
除非我在一天的这个时候失去了大脑,否则这比64位整数大 .
Scato wrotes:
十六进制小数是无符号正值,因此0x80000000 = 2147483648 - 这在数学上是正确的 . 如果要使其成为有符号值,则必须右移:0x80000000 >> 0 = -2147483648 . 你也可以写1 << 31 .
在Google Chrome内置的javascript中,您可以在号码被称为无限之前转到大约2 ^ 1024 .
基本上javascript不支持很长时间 .
所以对于它可以表示小于32位的正常值,它将使用int类型容器 . 对于大于32位的整数值,它使用double . 在双重复位中,整数部分为53位,其余为尾数(以保持浮点信息) .
所以你可以使用
2^53 - 1
,其值是9007199254740991
您可以通过
Number.MAX_SAFE_INTEGER
访问代码中使用的值简短的回答是“它取决于” .
如果您在任何地方使用按位运算符(或者如果您指的是数组的长度),则范围为:
未签名:
0…(-1>>>0)
签名:
(-(-1>>>1)-1)…(-1>>>1)
(碰巧的是,按位运算符和数组的最大长度限制为32位整数 . )
如果您不使用按位运算符或使用数组长度:
签名:
(-Math.pow(2,53))…(+Math.pow(2,53))
这些限制是由“数字”类型的内部表示强加的,其通常对应于IEEE 754双精度浮点表示 . (注意,与典型的有符号整数不同,负极限的大小与正极限的大小相同,这是由于内部表示的特征,实际上包括负0!)
Number.MAX_VALUE表示JavaScript中可表示的最大数值 .
由于似乎没有人这样说过,在 v8 引擎中,
31 bits
数字和数字的行为存在差异 .如果你有
32 bits
,你可以使用第一位告诉javascript引擎该数据是什么类型,并让剩余的位包含实际数据 . 这就是 V8 作为31 bis
numbers
的一个小优化所做的事情(或曾经做过,我的来源已经过时了) . 最后一个31 bits
是数字值,然后第一个位告诉引擎它是数字还是对象引用 .但是,如果您使用
31 bits
以上的数字,那么数据将赢得't fit in, the number will be boxed in 64 bits double and the optimisation won' .在下面的视频中,底线是:
interesting video
Other source
其他人可能已经给出了通用的答案,但我认为快速确定它是一个好主意:
这让我在Chrome 30中不到一毫秒的时间内获得9007199254740992 .
它将测试2的幂,以找到哪一个,当'添加'1时,等于他自己 .
您想要用于按位运算的任何内容必须介于0x80000000(-2147483648或-2 ^ 31)和0x7fffffff(2147483647或2 ^ 31-1)之间 .
控制台将告诉您0x80000000等于2147483648,但0x80000000和0x80000000等于-2147483648 .