※ 引述《cyclone350 (老子我最神)》之铭言:
: 纯抱怨
: 不知道大家是怎么跟 PM 谈需求的
: 我最近谈需求快要崩溃了
: 我明明只是一个很单纯很简单的疑问
: 莫名其妙就要讲一小时,而且跟我的问题完全无关
: 我每次希望把问题拉回来,但 PM 就是会把问题奇妙化,讲一堆五四三
: 举个例子:
: PM 提了一个打折需求,我需要知道若商品打折后有小数点是如何进位
: 1. 四舍五入 2. 无条件进位 3. 无条件舍去
离题一下, 这个问题其实比想像中要麻烦.
举个例 (compiler 与 compiler option 若不同结果可能也有差异)
int price = 25;
float discount = 0.88;
printf("%.10f\n", price * discount); // 21.9999998808
printf("%d\n", (int)(price * discount)); // 21
printf("%d\n", (int)floorf(price * discount)); // 22
printf("%d\n", (int)(price * 0.88f)); // 21
printf("%d\n", (int)(price * 0.88)); // 22
printf("%d\n", 1191567 * 88 / 100); // 1048578
printf("%d\n", (int)(1191567 * 0.88)); // 1048578
printf("%d\n", (int)floorf(1191567 * 0.88)); // 1048579
printf("%d\n", (int)floor(1191567 * 0.88)); // 1048578
就算用 double 提高精确度, 浮点的四舍五入也要先厘清
round half away from zero, round half to even 等差异
IEEE 754 默认用 round half to even (banker's rounding) 跟小学数学教的不同
在值域容许的范围内, 改用整数运算比较不容易出错.
N 如果要打 88 折, 会变成
无条件舍去 (N * 88) / 100
小学四舍五入 ((N * 88) + (100 / 2)) / 100
无条件进位 ((N * 88) + (100 - 1)) / 100
实际上线前还有些问题需要 PM 先想清楚
比如说买了一堆东西, 打折是总价打折还是单价打折加总?