سؤال

أحاول حساب وظيفة js 'modulo، ولكن لا تحصل على النتيجة الصحيحة (والتي يجب أن تكون 1). فيما يلي قطعة من التعليمات البرمجية الصغار.

var checkSum = 210501700012345678131468;
alert(checkSum % 97);

Result: 66

ما هي المشكلة هنا؟

التحيات، benedikt.

هل كانت مفيدة؟

المحلول

حفنة من التحسينات إلى إصدار Benedikt: "Crest + = '' '' ADIVENT؛" هو bugfix؛ تبادل (مقاسي) يجعل من الممكن نقل الحجج كسلاسل؛ تحقق من وجود سلسلة فارغة في النهاية يجعلها دائما إعادة القيم العددية؛ البيانات الافتراضية المضافة لذلك لا تستخدم المتغيرات العالمية؛ تحويلها إلى النمط القديم لأنه يعمل في المتصفحات مع جافا سكريبت القديمة؛ إصلاح كريست == 0؛ علة (شكرا @ dan.stackoverflow).

وظيفة modulo (الفنان، المقسوم) {var cdivident = ''؛ var crest = ''؛ ل (var i في المناشر) {var cchar = الفنان [i]؛ Var Caperator = Crest + '' '+ CDIVIMD +' '+ CCAR؛ إذا (Croperator <parseint (divisor)) {cdivident + = '' + cchar؛ } آخر {crest = croperator٪ مقسم؛ إذا (crest == 0) {crest = ''؛ } CDIVIMD = ''؛ }} كريست + = '' + edifident؛ إذا (crest == '') {crest = 0؛ } عودة كريست؛ }

نصائح أخرى

بالنسبة لحساب IBAN، تشكل رقم مصرفي عادي في نهاية المطاف مع عدد كبير جدا يحتوي على نموذج بيانات السلسلة. من هذا الرقم الكبير، يجب أن أجد الباقي عند مقسوم 97 -> عدد كبير من٪ 97.

بمجرد تحويل نوع البيانات إلى عدد صحيح، أحصل على تجاوز سعة مما يؤدي إلى عدد صحيح سلبي وفي النهاية قيمة بقية خاطئة. كما رأيت بعض القطع السفلية من التعليمات البرمجية (والذي أعطى أيضا نتيجة خاطئة)، لم أستطع مقاومة مشاركة بلدي. الاعتمادات تذهب إلى العثور على معامل عدد كبير جدا مع عدد عادي

modulo: function(divident, divisor) {
    var partLength = 10;

    while (divident.length > partLength) {
        var part = divident.substring(0, partLength);
        divident = (part % divisor) +  divident.substring(partLength);          
    }

    return divident % divisor;
}

NB أستخدم 10 مواقع هنا لأن هذا أصغر من 15 (وبعضها) من مواضع عدد صحيح بحد أقصى في جافا سكريبت، فإنه ينتج عنه رقم أكبر من 97 وهو رقم جولة لطيفة. أول حجتين مسألة.

يبدو أنك سقطت ضحية لهذا: ما هي أعلى قيمة عدد صحيح JavaScript أن الرقم يمكن أن يذهب إلى دون فقدان الدقة؟

فقط لإعادة التأكيد على ما هو في الخيط الآخر:

إنها قيم نقطة عائمة 64 بت، وهي أكبر قيمة متكاملة دقيقة هي 2 ^ 53. ومع ذلك، من قسم المواصفات [8.5: نوع الرقم]:

يتعامل بعض مشغلي Ecascript فقط بأعداد صحيحة في المدى -2 ^ 31 إلى 2 ^ 31-1، شامل، أو في النطاق 0 إلى 2 ^ 32-1، شاملة. يقبل هؤلاء المشغلون أي قيمة من نوع الرقم ولكن أولا تحويل كل قيمة من هذا القبيل إلى واحد من 2 ^ 32 القيم الصحيحة. انظر أوصاف مشغلي TOINT32 و Touint32 في الأقسام 0 و 0، على التوالي

لكن الائتمان حيث الائتمان مستحق. حصلت جيمي الإجابة المقبولة هناك للقيام بذكاء (حسنا، googling).

أخيرا، حلاي:

function modulo (divident, divisor) {
    cDivident = '';
    cRest = '';

    for each ( var cChar in divident ) {
        cOperator = cRest + '' + cDivident + '' + cChar;

        if ( cOperator < divisor ) {
            cDivident += '' + cChar;
        } else {
            cRest = cOperator % divisor;
            if ( cRest == 0 ) cRest = '';
            cDivident = '';
        }

    }

    return cRest;
}

بالنسبة لأولئك الذين يرغبون ببساطة في نسخ ولصق حل عمل (وظيفي) في ES6 للتحقق من العيادات:

function isIBAN(s){
    const rearranged = s.substring(4,s.length) + s.substring(0,4);
    const numeric   = Array.from(rearranged).map(c =>(isNaN(parseInt(c)) ? (c.charCodeAt(0)-55).toString() : c)).join('');
    const remainder = Array.from(numeric).map(c => parseInt(c)).reduce((remainder, value) => (remainder * 10 + value) % 97,0);

    return  remainder === 1;}

يمكنك حتى كتابة ذلك كأبطانة واحدة.

يتم تنفيذ عملية modulo على مجموعة أعداد صحيحة تخزين الرقم الفعلي (divident, ، تطبق كسلسلة تعمل):

function modulo(divident, divisor){
   return Array.from(divident).map(c => parseInt(c)).reduce((remainder, value) => (remainder * 10 + value) % divisor,0);
};

هذا يعمل لأن modulo توزيع أكثر من الجمع والترقيط والضرب:

  • (A + B)٪ M = ((٪ م) + (B٪ م))٪ م
  • (AB)٪ م = ((٪ م) - (B٪ م))٪ م
  • ب)٪ م = ((٪ م)(B٪ م))٪ م

تبدو وظيفة IBAN Transpiled إلى ES5

function (s) {
    var rearranged = s.substring(4, s.length) + s.substring(0, 4);
    var numeric = Array.from(rearranged).map(function (c) { return (isNaN(parseInt(c)) ? (c.charCodeAt(0) - 55).toString() : c); }).join('');
    var remainder = Array.from(numeric).map(function (c) { return parseInt(c); }).reduce(function (remainder, value) { return (remainder * 10 + value) % 97; }, 0);
    return remainder === 1;
};

طورت صامت مات جافا سكريبت مكتبة للأعداد الصحيحة الكبيرة. يمكن أن يحل هذه المشكلة أيضا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top