我被问到以下问题,我不知道如何回答。我想知道是否有人可以提供帮助:
使用C#,不使用任何数学函数(不允许使用Round()和Truncate())使用以下双3.009784654并将其四舍五入到小数点后4位。
这是面试,不是课堂项目或家庭作业。面试官似乎试图让我使用mod,但我仍然想不出怎么做。
谢谢!
答案 0 :(得分:7)
要截断(因为未指定舍入规则):乘以1e4,强制转换为int,除以1e4。
答案 1 :(得分:2)
这是一个糟糕的面试问题,因为考虑到预期的工具,任务通常是不可能的,因为大多数正确的结果都无法表示。也就是说,公共浮点类型无法准确表示正确的数学结果3.0098。因此无法计算并返回正确的答案。您将不得不使用一些替代机制,例如以不同的类型返回值(缩放为整数,字符串,十进制浮点格式等)。
我怀疑面试官可能期望的答案是评估(int)(x * 10000 + .5)*。0001。这会对值进行缩放,以使所需结果为整数(舍入量子,.0001,缩放为1),添加.5,截断为整数,并反转缩放。添加.5和截断的组合几乎等于舍入,除非它要求x为正,舍入为零,并且具有范围/域问题。可根据情况和所需行为对这些进行调整。当然,由于无法表示准确的结果,答案通常略有不正确。
更有趣的答案是评估(x * 10000 + 0x1p52-0x1p52)*。0001。这会使用当前浮点舍入模式对值进行缩放,将其舍入为整数,并撤消缩放。舍入是有效的,因为公共双精度型有效位为53位,因此,当高位值为0x1p52(2 52 )时,低位值为0x1p0(2 0 < / sup>,也称为1)。为了产生添加0x1p52的结果,有效数必须舍入,这在浮点硬件中自动完成。然后减去0x1p52将删除添加的数字,保留舍入值。和以前一样,有一些关于范围/域的警告,并确保编译器执行双精度算术而不是更多,并且可以进行调整。但是,它在某些硬件上比转换为整数和返回更快。
使用fmod或字符串转换的性能更差,因为它们需要除法,这在大多数常见处理器上都很慢。
答案 2 :(得分:1)
乘以10 ^ numberOfDigitsAfterComma,转换为int然后再回到float并除以10 ^ ...
double x = 3.009784654;
x = ((double)((int)(x * 10000))) / 10000;
答案 3 :(得分:1)
如果你真的需要mod,你可以这样做:
double number = 3.009784654;
double truncatedNumber = number - number % 0.0001;
答案 4 :(得分:0)
使用mod的答案:
double d = 1.23456789;
int digitsToKeep = 2;
double divisor = Math.Pow(10, digitsToKeep * -1);
double rounded = d - (d % divisor);
答案 5 :(得分:0)
如果需要,还可以将数字向上舍入。
public static double Round(double number, int digits)
{
for (int i = 0; i < digits; i++)
number *= 10;
int whole = (int)number;
double fraction = number - whole;
if (fraction >= 0.5)
whole++;
number = whole;
for (int i = 0; i < digits; i++)
number /= 10.0;
return number;
}