RGJ
(Richard - Communiteq)
14.Январь.2026 17:44:11
1
Использование Discourse-Subscriptions
Попытка добавить тарифный план к продукту
Введите 19.99 в поле цены (это уже сложно, так как поле ввода ведёт себя очень странно)
Попробуйте отправить форму
Получите ошибку «Invalid integer 1998.9999999999998»
Пока я тестировал это только на стабильной версии 3.5.3, но код в бета-версии тот же.
Код
@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);
}
Проблема с числами с плавающей запятой в JavaScript / IEEE-754:
-> parseFloat("19.99")*100
<- 1998.9999999999998
Предлагаемое исправление: const decimal = Math.round(Number(value) * 100)
Мой главный вопрос: почему никто этого не заметил? Разве кто-то раньше не устанавливал цену в $19.99?
Кстати, я также часто получаю NaN, например, когда полностью очищаю поле ввода.
2 лайка
pfaffman
(Jay Pfaffman)
14.Январь.2026 17:50:20
2
I knew right away. One more thing I learned about computers 40+ years ago that’s not changed.
Or use 1-cent integers? I think that’s what Stripe does, actually. (But your solution requires changing much less code, so I guess it wins.)
2 лайка
RGJ
(Richard - Communiteq)
14.Январь.2026 17:52:07
3
Yes, that’s what it does, unit_amount are cents and the amountDollars is an ‘XX.XX’ input value.
The “invalid integer” error even comes from the Stripe API.
I guess we’re both old enough to know about the FDIV bug
3 лайка
sam
(Sam Saffron)
15.Январь.2026 03:59:56
4
honestly I think storing this in a float is misguided this column should be an int and stored in cents
3 лайка
RGJ
(Richard - Communiteq)
15.Январь.2026 04:35:55
5
It is, the parseFloat is used to convert from/to input field which is “currency with two decimals”. The unit_amount object property is obviously typeless though, hence my suggestion to use Math.round()
It is not a column server side, it is passed to the Stripe API.
1 лайк
For currency BCD floating point is generally better than binary floating point.
Спасибо @RGJ за отчет — это должно исправить проблему
main ← fix/subscription-price-floating-point
merged 05:22PM - 20 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 07:00:27
10
Эта тема была автоматически закрыта через 2 дня. Новые ответы больше не принимаются.