Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 在格式化用于显示的浮点时限制小数位数和总位数_Objective C_Cocoa Touch_Nsnumberformatter_Decimal Point - Fatal编程技术网

Objective c 在格式化用于显示的浮点时限制小数位数和总位数

Objective c 在格式化用于显示的浮点时限制小数位数和总位数,objective-c,cocoa-touch,nsnumberformatter,decimal-point,Objective C,Cocoa Touch,Nsnumberformatter,Decimal Point,我需要以最有效的方式在有限宽度的区域打印浮点值。我使用的是NSNumberFormatter,我将小数点后的两个数字设置为默认值,这样当我有一个像234.25这样的数字时,它就会按原样打印:234.25。但是当我有1234.25时,我希望它被打印为:1234.3,并且11234.25应该被打印11234 我需要点后最多两位数字,如果点后有数字,则总共最多五位数字,但如果整数部分有更多数字,则打印的数字也应超过五位 我看不出有能力限制NSNumberFormatter中的总位数。这是否意味着我应该

我需要以最有效的方式在有限宽度的区域打印浮点值。我使用的是
NSNumberFormatter
,我将小数点后的两个数字设置为默认值,这样当我有一个像
234.25
这样的数字时,它就会按原样打印:
234.25
。但是当我有
1234.25
时,我希望它被打印为:
1234.3
,并且
11234.25
应该被打印
11234

我需要点后最多两位数字,如果点后有数字,则总共最多五位数字,但如果整数部分有更多数字,则打印的数字也应超过五位


我看不出有能力限制
NSNumberFormatter
中的总位数。这是否意味着我应该编写自己的函数以这种方式格式化数字?如果是这样,那么获取整数和小数部分的位数的正确方法是什么?我还更喜欢使用
CGFLoat
,而不是
NSNumber
,以避免额外的类型转换。

代码:

#define INTPARTSTR(X) [NSString stringWithFormat:@"%d",(int)X]
#define DECPARTSTR(X) [NSString stringWithFormat:@"%d",(int)(((float)X-(int)X)*100)]

- (NSString*)formatFloat:(float)f
{
    NSString* result;

    result = [NSString stringWithFormat:@"%.2f",f];

    if ([DECPARTSTR(f) isEqualToString:@"0"]) return INTPARTSTR(f);
    if ([INTPARTSTR(f) length]==5) return INTPARTSTR(f);

    if ([result length]>5)
    {
        int diff = (int)[result length]-7;

        NSString* newResult = @"";

        for (int i=0; i<[result length]-diff-1; i++)
            newResult = [newResult stringByAppendingFormat:@"%c",[result characterAtIndex:i]];

        return newResult;
    }


    return result;
}
- (void)awakeFromNib
{
    NSLog(@"%@",[self formatFloat:234.63]);
    NSLog(@"%@",[self formatFloat:1234.65]);
    NSLog(@"%@",[self formatFloat:11234.65]);
    NSLog(@"%@",[self formatFloat:11234]);
}
2012-04-26 19:27:24.429 newProj[1798:903] 234.63
2012-04-26 19:27:24.432 newProj[1798:903] 1234.6
2012-04-26 19:27:24.432 newProj[1798:903] 11234
2012-04-26 19:27:24.432 newProj[1798:903] 11234
输出:

#define INTPARTSTR(X) [NSString stringWithFormat:@"%d",(int)X]
#define DECPARTSTR(X) [NSString stringWithFormat:@"%d",(int)(((float)X-(int)X)*100)]

- (NSString*)formatFloat:(float)f
{
    NSString* result;

    result = [NSString stringWithFormat:@"%.2f",f];

    if ([DECPARTSTR(f) isEqualToString:@"0"]) return INTPARTSTR(f);
    if ([INTPARTSTR(f) length]==5) return INTPARTSTR(f);

    if ([result length]>5)
    {
        int diff = (int)[result length]-7;

        NSString* newResult = @"";

        for (int i=0; i<[result length]-diff-1; i++)
            newResult = [newResult stringByAppendingFormat:@"%c",[result characterAtIndex:i]];

        return newResult;
    }


    return result;
}
- (void)awakeFromNib
{
    NSLog(@"%@",[self formatFloat:234.63]);
    NSLog(@"%@",[self formatFloat:1234.65]);
    NSLog(@"%@",[self formatFloat:11234.65]);
    NSLog(@"%@",[self formatFloat:11234]);
}
2012-04-26 19:27:24.429 newProj[1798:903] 234.63
2012-04-26 19:27:24.432 newProj[1798:903] 1234.6
2012-04-26 19:27:24.432 newProj[1798:903] 11234
2012-04-26 19:27:24.432 newProj[1798:903] 11234

您正在寻找“最大有效数字”和“最大分数数字”的组合,以及特定的舍入行为<代码>NSNumberFormatter等于任务:

float twofortythreetwentyfive = 234.25;
float onetwothreefourtwentyfive = 1234.25;
float eleventwothreefourtwentyfive = 11234.25;

NSNumberFormatter * formatter =  [[NSNumberFormatter alloc] init];
[formatter setUsesSignificantDigits:YES];
[formatter setMaximumSignificantDigits:5];
[formatter setMaximumFractionDigits:2];
[formatter setRoundingMode:NSNumberFormatterRoundCeiling];

NSLog(@"%@", [formatter stringFromNumber:[NSNumber numberWithFloat:twofortythreetwentyfive]]);
NSLog(@"%@", [formatter stringFromNumber:[NSNumber numberWithFloat:onetwothreefourtwentyfive]]);
NSLog(@"%@", [formatter stringFromNumber:[NSNumber numberWithFloat:eleventwothreefourtwentyfive]]);
结果:

2012-04-26 16:32:04.481有效数字[11565:707]234.25
2012-04-26 16:32:04.482有效数字[11565:707]1234.3
2012-04-26 16:32:04.483有效数字[11565:707]11235


下面是我如何在代码中实现这一点的。我不知道它的效率有多高,我希望还不错

所以我创建了一个全局NSNumberFormatter

NSNumberFormatter* numFormatter; 
然后在某个地方初始化它:

numFormatter=[[NSNumberFormatter alloc]init];
然后我使用以下函数格式化数字:

- (NSString*)formatFloat:(Float32)number withOptimalDigits:(UInt8)optimalDigits maxDecimals:(UInt8)maxDecimals
{
    NSString* result;
    UInt8 intDigits=(int)log10f(number)+1;
    NSLog(@"Formatting %.5f with maxDig: %d maxDec: %d intLength: %d",number,optimalDigits,maxDecimals,intDigits);  

    numFormatter.maximumFractionDigits=maxDecimals;
    if(intDigits>=optimalDigitis-maxDecimals) {
        numFormatter.usesSignificantDigits=YES;
        numFormatter.maximumSignificantDigits=(intDigits>optimalDigits)?intDigits:optimalDigits;
    } else {
        numFormatter.usesSignificantDigits=NO;
    }
    result = [numFormatter stringFromNumber:[NSNumber numberWithFloat:number]];

    return result;
}

在iOS 8上同时使用
nsnumberforamter
上的
maximumFractionDigits
maximumSignificantDigits
时,这是一个错误吗

        NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
        formatter.maximumFractionDigits = 2;  
        formatter.maximumSignificantDigits = 3;
        NSLog(@"%@", [formatter stringFromNumber:@(0.3333)]); // output 0.333 expected 0.33
如果我只使用
maximumFractionDigits

        NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
        formatter.maximumFractionDigits = 2;
        NSLog(@"%@", [formatter stringFromNumber:@(0.3333)]); // output expected .33

谢谢。这看起来很简单。但如果我有号码:211234.25,它将返回211230。但我希望它返回211234,这样它只对浮点部分进行四舍五入,而整数部分应该保持不变。使用NSNumberFormatter是否仍然可行?因此,我希望打印号码的最佳长度不超过5位。所以,如果有,我会把它全部打印出来,但是你没有固定的宽度。老实说,我不知道如何让
NSNumberFormatter
做到这一点;在我看来,如果输入的log10(大约等于整数部分的长度-1)大于5,就可以截断输入。对不起,我应该说得更清楚一些。我所说的宽度是指以像素为单位的宽度。所以我想用给定的像素区域来最有效地显示一个数字。哦,我明白了。我认为如果您想使用
NSNumberFormatter
,如果输入的数字太长,您每次都必须更改一点设置。否则的话,我想按照Kameleon博士的思路定制一个函数似乎是最好的选择。谢谢。这种实现看起来相当普遍,但我担心效率。可以使用比NSString更有效的方法吗?或者除了计算字符串的长度外,没有办法计算数字中的位数?在程序运行的所有时间里,我将在动画的每一帧中连续地进行这种转换。这不是很难吗?@BartoNaz:一个数字以10为底的对数大约是其整数位数的长度-1:
log10f(11123.25)->4.046221
是的,对数是个好主意。我将尝试制作类似@Dr.Kameleon的东西,但是使用对数而不是NSString。巴托纳兹刚刚读了其他的评论。我想我也同意,日志似乎是一个非常有趣的补充…:-)