RGJ
(Richard - Communiteq)
1
- Discourse-Subscriptions 사용 중
- 상품에 가격 플랜을 추가하려는 중
- 가격 입력란에 19.99 입력 (입력란의 동작이 매우 이상해서 이 단계조차 어렵습니다)
- 제출 시도
- “Invalid integer 1998.9999999999998” 오류 발생
아직 stable 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);
}
Javascript / IEEE-754 부동소수점의 문제:
-> parseFloat("19.99")*100
<- 1998.9999999999998
제안하는 수정안: const decimal = Math.round(Number(value) * 100)
가장 궁금한 점: 왜 아무도 이 문제를 발견하지 못했을까요? 이전에 $19.99로 가격을 설정해 본 사람이 없었나요?
참고로, 입력란을 완전히 비워두면 NaN 오류가 자주 발생합니다.
2개의 좋아요
pfaffman
(Jay Pfaffman)
2
나는 바로 알았어. 40년 전 이상으로 컴퓨터에 대해 배웠지만 변하지 않은 또 하나의 사실이지.
혹은 1센트 단위의 정수를 사용하는 건 어때? 실제로 스트라이프(Stripe)가 그렇게 하는 것 같아. (하지만 네 해결책이 훨씬 적은 코드 수정을 요구하니까, 아마도 네 쪽이 이기는 거겠지.)
2개의 좋아요
RGJ
(Richard - Communiteq)
3
네, 맞습니다. unit_amount는 센트 단위이며, amountDollars는 ‘XX.XX’ 형식의 입력 값입니다.
“invalid integer” 오류조차도 Stripe API에서 발생합니다.
우리 둘 다 FDIV 버그에 대해 알고 있을 정도로 나이가 많네요 
3개의 좋아요
sam
(Sam Saffron)
4
솔직히 말해서, 이 값을 float로 저장하는 것은 잘못된 접근이라고 생각해요. 이 컬럼은 int 타입이어야 하고, 센트 단위로 저장하는 게 맞아요.
3개의 좋아요
RGJ
(Richard - Communiteq)
5
그렇습니다. parseFloat는 “소수점 둘째 자리까지 표시되는 통화” 형식의 입력 필드에서 값을 변환하는 데 사용됩니다. unit_amount 객체 속성은 명백히 타입이 없으므로, Math.round()를 사용하라고 제안한 것입니다.
이는 서버 측의 컬럼이 아니라, Stripe API로 전달되는 값입니다.
1개의 좋아요
통화 BCD의 경우, 부동 소수점은 일반적으로 이진 부동 소수점보다 더 적합합니다.
@RGJ 님, 보고해 주셔서 감사합니다. 이 수정으로 해결될 것입니다 
2개의 좋아요
이 주제는 2일 후 자동으로 닫혔습니다. 더 이상 새 답변을 남길 수 없습니다.