Objective-C:正确地将地板重叠为3位小数

时间:2013-06-18 02:17:34

标签: objective-c math rounding floor

我试图将浮点值设置为第三个小数。例如,值2.56976应为2.569而不是2.570。我搜索并找到了这样的答案:

floor double by decimal place

这样的答案并不准确。例如代码:

double value = (double)((unsigned int)(value * (double)placed)) / (double)placed

可以返回value - 1,但这不正确。值和value * (double)placed)的乘法可能会引入类似于:2100.999999996。当更改为unsigned int时,它变为2100,这是错误的(正确的值应该是2101)。其他答案也有同样的问题。在Java中,您可以使用BigDecimal来保存所有哈希值。

(注意:当然,舍入2100.9999不是一个选项,因为它会破坏整个地板的概念,正确地计算3小时​​")

3 个答案:

答案 0 :(得分:0)

以下代码应该有效:

#include <stdio.h>
#include <math.h>
int main(void) {
    double value = 1.23456;
    double val3;
    val3 = floor(1000.0 * value + 0.0001) * 0.001; // add 0.0001 to "fix" binary representation problem
    printf("val3 is %.8f; the error is %f\n", val3, 1.234 - val3);
}

打印出来

val3 is 1.23400000; the error is 0.000000

如果存在任何残留错误,那么浮点数无法准确表示这一事实 - BigDecimal背后的想法和类似的事情是以非常明确的方式解决这个问题(例如通过表示数字作为数字,而不是二进制表示 - 效率较低,但保持准确性)

答案 1 :(得分:0)

我不得不考虑一个涉及NSString的解决方案,它就像一个魅力。这是完整的方法:

- (float) getFlooredPrice:(float) passedPrice {

    NSString *floatPassedPriceString = [NSString stringWithFormat:@"%f", passedPrice];
    NSArray *floatArray = [floatPassedPriceString componentsSeparatedByString:@"."];
    NSString *fixedPart = [floatArray objectAtIndex:0];
    NSString *decimalPart = @"";
    if ([floatArray count] > 1) {
        NSString *decimalPartWhole = [floatArray objectAtIndex:1];
        if (decimalPartWhole.length > 3) {
            decimalPart = [decimalPartWhole substringToIndex:3];
        } else {
            decimalPart = decimalPartWhole;
        }
    }
    NSString *wholeNumber = [NSString stringWithFormat:@"%@.%@", fixedPart, decimalPart];

    return [wholeNumber floatValue];

}

答案 2 :(得分:0)

  

例如,值2.56976应为2.569而不是2.570

解决方案很简单:

double result = floor(2.56976 * 1000.0) / 1000.0;

我不知道为什么你会搜索并发症......这很有效,不需要通过一些unsigned int或其他+ 0.0001或其他任何东西。

重要提示:

NSLog(@"%.4f", myDouble);

实际上对你的变量做一轮。因此,相信你可以使用%.Xf

是不合适的