RGJ
(Richard - Communiteq)
14 يناير 2026، 5:44م
1
استخدام Discourse-Subscriptions
محاولة إضافة خطة تسعير إلى منتج
إدخال 19.99 في خانة السعر (هذا صعب بالفعل لأن الإدخال يتصرف بغرابة شديدة)
محاولة الإرسال
الحصول على الخطأ “Invalid integer 1998.9999999999998” (عدد صحيح غير صالح 1998.9999999999998)
لقد اختبرت هذا فقط على الإصدار المستقر 3.5.3 حتى الآن، لكن الكود هو نفسه في النسخة التجريبية (beta).
Code
@computed("unit_amount")
get amountDollars() {
return parseFloat(this.get("unit_amount") / 100).toFixed(2);
}
set amountDollars(value) {
const decimal = parseFloat(value) * 100;
this.set("unit_amount", decimal);
}
خبث أرقام الفاصلة العائمة في جافاسكريبت / IEEE-754:
-> parseFloat("19.99")*100
<- 1998.9999999999998
الحل المقترح: const decimal = Math.round(Number(value) * 100)
سؤالي الأكبر: لماذا لم يلاحظ أحد؟ ألم يقم أحد بتعيين السعر على 19.99 دولارًا من قبل؟
إعجابَين (2)
pfaffman
(Jay Pfaffman)
14 يناير 2026، 5:50م
2
عرفت ذلك على الفور. شيء آخر تعلمته عن أجهزة الكمبيوتر منذ أكثر من 40 عامًا لم يتغير.
أو استخدام أعداد صحيحة بفئة 1 سنت؟ أعتقد أن هذا ما تفعله Stripe، في الواقع. (لكن حلك يتطلب تغيير قدر أقل بكثير من التعليمات البرمجية، لذا أعتقد أنه يفوز.)
إعجابَين (2)
RGJ
(Richard - Communiteq)
14 يناير 2026، 5:52م
3
نعم، هذا ما يفعله، unit_amount هي سنتات و amountDollars هي قيمة إدخال “XX.XX”.
خطأ “العدد الصحيح غير الصالح” يأتي حتى من واجهة برمجة تطبيقات Stripe.
أعتقد أننا كلينا كبيران بما يكفي لمعرفة خطأ FDIV
3 إعجابات
sam
(Sam Saffron)
15 يناير 2026، 3:59ص
4
بصراحة، أعتقد أن تخزين هذا في عدد عشري (float) هو أمر مضلل، يجب أن يكون هذا العمود عددًا صحيحًا (int) ومخزنًا بالسنتات.
3 إعجابات
RGJ
(Richard - Communiteq)
15 يناير 2026، 4:35ص
5
إنها كذلك، يتم استخدام parseFloat للتحويل من/إلى حقل الإدخال وهو “عملة بعلامتين عشريتين”. من الواضح أن خاصية الكائن unit_amount عديمة النوع، ومن هنا جاء اقتراحي باستخدام Math.round().
إنها ليست عمودًا من جانب الخادم، بل يتم تمريرها إلى واجهة برمجة تطبيقات Stripe.
إعجاب واحد (1)
بالنسبة للعملة، فإن النقطة العائمة BCD أفضل بشكل عام من النقطة العائمة الثنائية.
شكرًا @RGJ على التقرير - هذا يجب أن يصلحه
main ← fix/subscription-price-floating-point
opened 11:10AM - 17 Feb 26 UTC
Setting a subscription price like $19.99 would fail with "Invalid integer 1998.9… 999999999998" from the Stripe API.
Due to IEEE-754 floating point arithmetic, `parseFloat("19.99") * 100` produces `1998.9999999999998` instead of `1999`. This non-integer value is then sent directly to Stripe which rejects it.
Wrapping the multiplication in `Math.round()` ensures the result is always a proper integer before being stored as `unit_amount`.
https://meta.discourse.org/t/393466
إعجابَين (2)
zogstrip
تم إغلاقه في
23 فبراير 2026، 7:00ص
10
تم إغلاق هذا الموضوع تلقائيًا بعد يومين. لم يعد الردود الجديدة مسموحًا بها.