【问题标题】:Convert float to float and truncate after two decimal places Objective-C将浮点数转换为浮点数并截断两位小数Objective-C
【发布时间】:2014-07-01 08:06:37
【问题描述】:

我有一个浮点数 var1 = cashInHandAmount = 4.73000002 我只是想: var2 = 4.73。

我试过这样:

NSString *floatString = [NSString stringWithFormat:@"%.02f",cashInHandAmount];//it prints 4.73
[self.editcash setMaxValue:[floatString floatValue]];//but it again sets 4.73000002 why?

你们能帮我解决这个问题吗?

【问题讨论】:

  • 您需要一个 NSNumberFormatter... 或更好地使用 NSDecimalNumber 因为您看到的是浮点存储的正常不准确性...您没有无限数量的位,因此只能代表有限小数位数
  • 我尝试过使用NSNumberFormatter,从字符串中获取数字时出现问题,将此数字转换为浮点数。转换后的浮点数显示小数点后8位
  • 浮点数将始终显示 8 位小数...使用 NSDecimalNumber
  • 每个程序员都应该知道的关于浮点数的知识:floating-point-gui.de

标签: iphone objective-c floating cgfloat


【解决方案1】:

%f 只是对输出进行四舍五入。如果确切的值(即 4.73)在浮点格式中没有表示,则将浮点值转换为字符串并返回不起作用。因此,将其转换回来会将存储的值 4.73“四舍五入”为浮点格式,这显然是 4.730…02。

您应该很少使用(二进制,IEEE)浮点数进行财务计算。财务价值(金额)在大多数情况下是美分的整数值,但没有美元(或其他)的浮动价值。此外,您可以考虑使用NSDecimalNSDecimalNumber 来确保每个具有两位精度的值都可以存储在格式中。

编辑:

float f = 4.73000002;
float rounded = roundf(f * 100.0f) / 100.0f;
NSLog(@"%10.10f", rounded);

输出:

2014-07-01 10:25:48.653 xctest[596:303] 4.7300000191

很难检查,但可能 float 不能准确表示 4.73。最接近的可表示值是 4.7300000191。这就是我所说的:四舍五入的十进制表示并不总是可能的“二进制浮点”表示。您将面临许多价值观的问题。

【讨论】:

    【解决方案2】:

    试试这个:

        float var1 = 4.73000002;
        NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
        formatter.numberStyle = NSNumberFormatterDecimalStyle;
        formatter.maximumFractionDigits = 2;  //Set number of fractional digits
    
        NSNumber *num = [NSNumber numberWithFloat:var1];
    
        NSString *roundedNum = [formatter stringFromNumber:num];
    
        DLOG(@"Answer : %@", roundedNum);
    

    【讨论】:

    • satishthanks for the answer,从 roundedNum 得到浮点变量?它将再次产生 4.7300000....
    • 您期望什么结果以及哪种数据类型?一个像浮点值 = 0.0 这样的浮点变量的变量,默认情况下总是导致浮点值最多 6 位小数,比如 0.000000
    【解决方案3】:

    如果你想截断所有其他小数,你可以声明一个简单的方法,如下所示:

    - (float)sanitizeFloat:(float)value
    {
        float newValue = [[NSString stringWithFormat:@"%.2f",value] floatValue];
        return newValue;
    }
    

    然后

    float aFloat = 45.070809;
    NSLog(@"%f",[self sanitizeFloat:aFloat]);
    

    在你的情况下:

    [self.editcash setMaxValue:[self sanitizeFloat:cashInHandAmount]];
    

    输出将是45.070000

    【讨论】:

      【解决方案4】:

      如果您使用具有固定小数位的货币金额,则应始终使用 NSDecimalNSDecimalNumber - 根本不应该使用浮点数,因为它们不精确。

      你可以使用:

      -[NSDecimalNumber decimalNumberWithString:]
      

      创建您的号码,并且有多种使用 NSDecimalNumbers 的方法 - 有关详细信息,请参阅 Apple's docsNSDecimalNumber.h

      【讨论】:

      • 它们不是不精确的,而是简单地四舍五入到它们的内部二进制表示。
      猜你喜欢
      • 2016-09-06
      • 1970-01-01
      • 2017-07-04
      • 1970-01-01
      • 1970-01-01
      • 2012-05-25
      • 2015-03-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多