javascript browser - ما هي القيمة الصحيحة القصوى لجافا سكريبت التي يمكن أن ينتقل إليها الرقم دون فقدان الدقة؟




incompatibilities issues (17)

كتب Scato:

يجب أن يكون أي شيء تريد استخدامه لعمليات التثبيث بين 0x80000000 (-2147483648 أو -2 ^ 31) و 0x7fffffff (2147483647 أو 2 ^ 31 - 1).

ستخبرك وحدة التحكم أن 0x80000000 يساوي +2147483648 ، ولكن 0x80000000 و 0x80000000 يساوي -2147483648

هيكس-عشرية هي قيم إيجابية غير موقعة ، لذلك 0x80000000 = 2147483648 - thats رياضيًا صحيحًا. إذا كنت تريد جعله قيمة موقعة ، فيجب أن تقوم بالتبديل إلى اليمين: 0x80000000 >> 0 = -2147483648. يمكنك كتابة 1 << 31 بدلاً من ذلك أيضًا.

هل هذا محدد من قبل اللغة؟ هل هناك حد أقصى محدد؟ هل هو مختلف في المتصفحات المختلفة؟


في JavaScript ، يوجد رقم يسمى Infinity .

أمثلة:

(Infinity>100)
=> true

// Also worth noting
Infinity - 1 == Infinity
=> true

Math.pow(2,1024) === Infinity
=> true

قد يكون هذا كافياً لبعض الأسئلة المتعلقة بهذا الموضوع.


تظهر العديد من الإجابات أعلاه النتيجة true 9007199254740992 === 9007199254740992 + 1
لأقول أن 9 007 199 254 740 991 هو العدد الصحيح الآمن الأقصى.

ماذا لو استمررنا في التراكم:

input: 9007199254740992 + 1  output: 9007199254740992  // expected: 9007199254740993
input: 9007199254740992 + 2  output: 9007199254740994  // expected: 9007199254740994
input: 9007199254740992 + 3  output: 9007199254740996  // expected: 9007199254740995
input: 9007199254740992 + 4  output: 9007199254740996  // expected: 9007199254740996

يمكن أن نكتشف ، من بين الأعداد الأكبر من 9 007 199 254 740 992 ، فقط الأرقام القابلة للتمثيل .

إنه إدخال لشرح كيفية عمل تنسيق ثنائي الدقة 64 بت على هذا. دعونا ننظر كيف يتم عقد 9 007 199 254 740 992 (ممثلة) باستخدام هذا التنسيق الثنائي.

نبدأ من 4 503 599 627 370 496 بالإصدار الموجز للنسق أولاً:

  1 . 0000 ---- 0000  *  2^52            =>  1  0000 ---- 0000.  
     |-- 52 bits --|    |exponent part|        |-- 52 bits --|

على الجانب الأيسر من السهم ، لدينا قيمة bit 1 ، ونقطة راديوية مجاورة ، ثم بضرب 2^52 ، فإننا نحرك النقطة 52 لنقطة الجذر ، وتنتقل إلى النهاية. الآن نحصل على 4503599627370496 في ثنائي.

الآن نبدأ في تجميع 1 إلى هذه القيمة حتى يتم تعيين كل البتات إلى 1 ، وهو يساوي 9 007 199 254 740 991 بالأرقام العشرية.

  1 . 0000 ---- 0000  *  2^52  =>  1  0000 ---- 0000.  
                       (+1)
  1 . 0000 ---- 0001  *  2^52  =>  1  0000 ---- 0001.  
                       (+1)
  1 . 0000 ---- 0010  *  2^52  =>  1  0000 ---- 0010.  
                       (+1)
                        . 
                        .
                        .
  1 . 1111 ---- 1111  *  2^52  =>  1  1111 ---- 1111. 

الآن ، سبب أنه في تنسيق ثنائي 64 بت الدقة المزدوجة ، فإنه يخصص بدقة 52 بت للكسر ، لا يوجد المزيد من البق متاح للحمل لإضافة واحد أكثر 1 ، لذلك ما يمكننا القيام به هو إعادة جميع البتات إلى 0 ، والتلاعب الجزء الأسى:

  |--> This bit is implicit and persistent.
  |        
  1 . 1111 ---- 1111  *  2^52      =>  1  1111 ---- 1111. 
     |-- 52 bits --|                     |-- 52 bits --|

                          (+1)
                                     (radix point have no way to go)
  1 . 0000 ---- 0000  *  2^52 * 2  =>  1  0000 ---- 0000. * 2  
     |-- 52 bits --|                     |-- 52 bits --|

  =>  1 . 0000 ---- 0000  *  2^53 
         |-- 52 bits --| 

الآن نحصل على 9 007 199 254 740 992 ، ومع العدد أكبر منه ، ما يمكن أن يحمله الشكل هو 2 مرة من الكسر :

                            (consume 2^52 to move radix point to the end)
  1 . 0000 ---- 0001  *  2^53  =>  1 0000 ---- 0001.  *  2
     |-- 52 bits --|                |-- 52 bits --|

لذلك عندما يصبح الرقم أكبر من 9 007 199 254 740 992 * 2 = 18 014 398 509 481 984 ، يمكن الاحتفاظ بـ 4 مرات فقط من الكسر :

input: 18014398509481984 + 1  output: 18014398509481984  // expected: 18014398509481985
input: 18014398509481984 + 2  output: 18014398509481984  // expected: 18014398509481986
input: 18014398509481984 + 3  output: 18014398509481984  // expected: 18014398509481987
input: 18014398509481984 + 4  output: 18014398509481988  // expected: 18014398509481988

ماذا عن الرقم بين [ 2 251 799 813 685 248 ، 4 503 599 627 370 496

 1 . 0000 ---- 0001  *  2^51  =>  1 0000 ---- 000.1
     |-- 52 bits --|                |-- 52 bits  --|

قيمة البت 1 بعد نقطة الجذر هي 2 ^ -1 بالضبط. (= 1/2 ، = 0.5) حتى عندما يكون الرقم أقل من 4 503 599 627 370 496 (2 ^ 52) ، يوجد بت واحد متاح لتمثيل 1/2 مرة من العدد الصحيح :

input: 4503599627370495.5   output: 4503599627370495.5  
input: 4503599627370495.75  output: 4503599627370495.5  

أقل من 2 251 799 813 685 248 (2 ^ 51)

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"

وما هو المدى المتاح للجزء الأسى ؟ الشكل allots 11 بت لذلك. شكل كامل من Wiki : (لمزيد من التفاصيل يرجى الذهاب إلى هناك)

لذا للحصول على 2 ^ 52 في الجزء الأس ، نحتاج بالضبط إلى تعيين e = 1075.


الجواب القصير هو أن يتوقف."

إذا كنت تستخدم معاملات البايت في أي مكان (أو إذا كنت تشير إلى طول المصفوفة) ، فإن النطاقات هي:

غير موقعة: 0…(-1>>>0)

توقيع: (-(-1>>>1)-1)…(-1>>>1)

(يحدث ذلك أن يتم تقييد عوامل البتات والحد الأقصى لطول مصفوفة إلى الأعداد الصحيحة 32 بت).

إذا كنت لا تستخدم معالجات البتّات أو تعمل بأطوال الصفيف:

التوقيع: (-Math.pow(2,53))…(+Math.pow(2,53))

يتم فرض هذه القيود من خلال التمثيل الداخلي لنوع "الرقم" ، والذي يتوافق عمومًا مع تمثيل نقطة عائمة مزدوجة الدقة IEEE 754. (لاحظ أنه على عكس الأعداد الصحيحة الموقعة النموذجية ، يكون حجم الحد السالب هو نفس حجم الحد الموجب ، بسبب خصائص التمثيل الداخلي ، والذي يتضمن فعليًا صفرًا سلبيًا !)


> = ES6: Number.MIN_SAFE_INTEGER; Number.MAX_SAFE_INTEGER; Number.MIN_SAFE_INTEGER; Number.MAX_SAFE_INTEGER;

<= ES5

من المرجع : Number.MAX_VALUE; Number.MIN_VALUE; Number.MAX_VALUE; Number.MIN_VALUE;

console.log('MIN_VALUE', Number.MIN_VALUE);
console.log('MAX_VALUE', Number.MAX_VALUE);

console.log('MIN_SAFE_INTEGER', Number.MIN_SAFE_INTEGER); //ES6
console.log('MAX_SAFE_INTEGER', Number.MAX_SAFE_INTEGER); //ES6


محاولة:

maxInt = -1 >>> 1

في Firefox 3.6 ، يكون 2 ^ 31 - 1.


تمثل إجابة جيمي بشكل صحيح الطيف صحيح جافا سكريبت المستمر كما -9007199254740992 إلى 9007199254740992 ضمنا (آسف 9007199254740993 ، قد تعتقد أنك 9007199254740993 ، ولكن كنت على خطأ! مظاهرة أدناه أو في jsfiddle ).

document.write(9007199254740993);

ومع ذلك ، لا توجد إجابة تكتشف / تثبت هذا بشكل برمجي (باستثناء جهاز CoolAJ86 الذي ألمح إليه في إجابته التي تنتهي في 28.56 عامًا ؛) ، لذا إليك طريقة أكثر فعالية قليلاً للقيام بذلك (على وجه الدقة ، إنها أكثر كفاءة حوالي 28.559999999968312 سنة :) ، جنبا إلى جنب مع اختبار كمان :

/**
 * 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);


يجب أن يكون أي شيء تريد استخدامه لعمليات التثبيث بين 0x80000000 (-2147483648 أو -2 ^ 31) و 0x7fffffff (2147483647 أو 2 ^ 31 - 1).

ستخبرك وحدة التحكم أن 0x80000000 يساوي +2147483648 ، ولكن 0x80000000 و 0x80000000 يساوي -2147483648.


أكتبه مثل هذا:

var max_int = 0x20000000000000;
var min_int = -0x20000000000000;
(max_int + 1) === 0x20000000000000;  //true
(max_int - 1) < 0x20000000000000;    //true

نفسه ل int32

var max_int32 =  0x80000000;
var min_int32 = -0x80000000;

يبدو أن Firefox 3 ليس لديه مشكلة في الأرقام الضخمة.

1e + 200 * 1e + 100 سيحسب غرامة إلى 1e + 300.

يبدو أن Safari ليس لديه مشكلة في ذلك أيضًا. (للسجل ، هذا موجود على جهاز Mac إذا قرر أي شخص آخر اختبار ذلك.)

ما لم أفقد عقلي في هذا الوقت من اليوم ، هذا هو أكبر من عدد صحيح 64 بت.


ومن 2 53 == 9 007 199 254 740 992. وذلك لأن يتم تخزين Number s كنقطة عائمة في عشري 52 بت.

قيمة الحد الأدنى هي -2 53 .

هذا يجعل بعض الأشياء الممتعة تحدث

Math.pow(2, 53) == Math.pow(2, 53) + 1
>> true

ويمكن أيضا أن تكون خطرة :)

var MAX_INT = Math.pow(2, 53); // 9 007 199 254 740 992
for (var i = MAX_INT; i < MAX_INT + 2; ++i) {
    // infinite loop
}

مزيد من القراءة: http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html


قد يكون الآخرون قد أعطوا الإجابة العامة بالفعل ، لكنني اعتقدت أنه من المستحسن إعطاء طريقة سريعة لتحديدها:

for (var x = 2; x + 1 !== x; x *= 2);
console.log(x);

والذي يعطيني 9007199254740992 في غضون أقل من ملي ثانية في Chrome 30.

سيختبر صلاحيات 2 لإيجاد أي واحد ، عندما "يضاف" 1 ، يساوي نفسه.


ECMAScript 6:

Number.MAX_SAFE_INTEGER = Math.pow(2, 53)-1;
Number.MIN_SAFE_INTEGER = -Number.MAX_SAFE_INTEGER;

اساسا javascript لا يدعم طويلة.
حتى بالنسبة للقيم العادية التي يمكن أن تمثل أقل من 32 بت ، ستستخدم حاوية نوع int. للحصول على قيم عددية أكبر ثم 32 بت ، فإن استخدامها مزدوج. في represntation مزدوجة الجزء الصحيح 53 بت والباقي هو عشري (للحفاظ على معلومات النقطة العائمة).
بحيث يمكنك استخدام 2^53 - 1 بقيمة 9007199254740991
يمكنك الوصول إلى القيمة لاستخدامها في التعليمات البرمجية الخاصة بك بواسطة Number.MAX_SAFE_INTEGER


يبدو أن كلا من Node.js و Google Chrome يستخدمان قيم نقطة عائمة 1024 بت:

Number.MAX_VALUE = 1.7976931348623157e+308

+/- 9007199254740991

قسم ECMA 8.5 - أرقام

لاحظ أن جميع الأعداد الصحيحة الموجبة والسالبة التي لا يزيد حجمها عن 2 53 يمكن تمثيلها في نوع الرقم (في الواقع ، يحتوي الرقم 0 على تمثيلين ، +0 و −0).

وهي قيم نقطة عائمة 64 بت ، وهي أكبر قيمة تكاملية بالضبط هي 2 9007199254740991 ، أو 9007199254740991 . في ES6 ، يتم تعريف هذا على أنه Number.MAX_SAFE_INTEGER .

لاحظ أن مشغلي bitwise و مشغلات shift يعملان على 32-bit ints ، لذا في هذه الحالة ، يكون العدد الصحيح الآمن الأقصى هو 2 31 -1 ، أو 2147483647.

اختبرها!

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

أجد هذا السؤال مثيرًا للاهتمام ، لأن أول تعرض جدي لبرمجة جافا سكريبت كان Node.js و AngularJS. لم أتعرف على jQuery أبداً ، وأعتقد أن هذا أمر جيد ، لأنني لا أضطر إلى إلغاء أي شيء. في الواقع ، أتجنب بنشاط حلول jQuery لمشاكلي ، وبدلاً من ذلك ، ابحث فقط عن طريقة AngularJS لحلها. لذا ، أعتقد أن إجابتي على هذا السؤال ستختفي أساسًا ، "فكر كمن لم يتعلم jQuery أبدًا" وتجنب أي إغراء لإدراج jQuery مباشرة (من الواضح أن AngularJS يستخدمه إلى حد ما خلف الكواليس).





javascript math browser cross-browser