5

如果我在 Objective-C 中执行以下操作:

NSString *result = [NSString stringWithFormat:@"%1.1f", -0.01];

它会给出结果@"-0.0"

有谁知道@"0.0"在这种情况下我如何强制结果(没有“-”)?

编辑:我尝试使用 NSNumberFormatter,但它有同样的问题。以下还产生@"-0.0"

double value = -0.01;
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:NSNumberFormatterDecimalStyle];
[numberFormatter setMaximumFractionDigits:1];
[numberFormatter setMinimumFractionDigits:1];
NSString *result = [numberFormatter stringFromNumber:[NSNumber numberWithDouble:value]];
4

4 回答 4

6

我想要一个通用的解决方案,独立于数字格式化程序的配置。

我使用了一个类别将功能添加到 NSNumberFormater;

@interface NSNumberFormatter (PreventNegativeZero)
- (NSString *)stringFromNumberWithoutNegativeZero:(NSNumber *)number;
@end

随着实施:

@implementation NSNumberFormatter (PreventNegativeZero)

- (NSString *)stringFromNumberWithoutNegativeZero:(NSNumber *)number
{
    NSString *const string = [self stringFromNumber: number];
    NSString *const negZeroString = [self stringFromNumber: [NSNumber numberWithFloat: -0.0f]];

    if([string isEqualToString: negZeroString])
    {
        NSString *const posZeroString = [self stringFromNumber: [NSNumber numberWithFloat: 0.0]];
        return posZeroString;
    }
    
    return string;
}

@end

这个怎么运作

关键功能是询问数字格式化程序它将如何格式化-0.0f(即浮点减零),NSString以便我们可以检测到这一点并采取补救措施。

为什么要这样做?根据格式化程序配置,-0.0f可以格式化为:@"-0", @"-0.0", @"-000", @"-0ºC", @"£-0.00", @"----0.0", @"(0.0)",@".⓪零"真的, 几乎任何东西。因此,我们询问格式化程序如何-0.0f使用以下行进行格式化:NSString *const negZeroString = [self stringFromNumber: [NSNumber numberWithFloat: -0.0f]];

有了不想要的-0.0f字符串,当任意输入数字被格式化时,可以测试它是否匹配不想要的-0.0f字符串。

第二个重要特征是数字格式化程序还被要求提供替换正零字符串。这是必要的,以便像以前一样尊重其格式。这是通过以下行完成的:[self stringFromNumber: [NSNumber numberWithFloat: 0.0]]

无效的优化

很想自己执行一个数字测试来确定输入数字是否会被格式化为-0.0f字符串,但这非常重要(即,一般来说基本上是不可能的)。这是因为将格式化为-0.0f字符串的数字集取决于格式化程序的配置。如果碰巧四舍五入到最接近的百万,那么-5,000f作为输入将被格式化为-0.0f字符串。

要避免的实现错误

当检测到格式化为-0.0f字符串的输入时,使用 生成一个正零等效输出字符串[self stringFromNumber: [NSNumber numberWithFloat: 0.0]]。请注意,特别是:

  • 代码格式化浮点文字0.0f并返回它。
  • 该代码使用输入的否定。

否定输入-0.1f将导致格式化0.1f。根据格式化程序的行为,这可能会被四舍五入并导致@"1,000"您不想要的结果。

最后说明

对于它的价值,这里使用的方法/模式/算法将转换为其他语言和不同的字符串格式化 API。

于 2013-11-18T13:26:24.720 回答
1

使用NSNumberFormatter. 一般来说,NSString格式不应该用于向用户呈现数据。

编辑:如问题所述,这不是正确的答案。有很多解决方案。检查负零很容易,因为它被定义为等于任何零 ( 0.0f == -0.0f),但实际问题是许多其他值可以四舍五入到负零。我建议不要捕获这些值,而是建议进行后处理 - 一个检查结果是否仅包含零位(跳过其他字符)的函数。如果是,请删除前导减号。

于 2012-06-10T16:52:55.223 回答
0
NSString *result = [NSString stringWithFormat:@"%1.1f", -0.01*-1];

如果您传递一个实例而不是一个值,您可以检查:

float myFloat = -0.01;
NSString *result = [NSString stringWithFormat:@"%1.1f", (myFloat<0? myFloat*-1:myFloat)];

编辑: 如果你只想 0.0 作为正值:

    NSString *result = [NSString stringWithFormat:@"%1.1f",(int)(myFloat*10)<0?myFloat:myFloat*-1];
于 2012-06-10T14:27:29.870 回答
0

通过采用 float 或 double 值将数字转换为 NSString。将字符串转换回 NSNumber。

NSDecimalNumber *num = [NSDecimalNumber decimalNumberWithString:@"-0.00000000008"];
    NSString *st2 = [NSString stringWithFormat:@"%0.2f", [num floatValue]];
    NSDecimalNumber *result = [NSDecimalNumber decimalNumberWithString:st2]; //returns 0
于 2015-04-15T19:17:13.950 回答