为什么这个 NSNumber 总和会返回一个奇怪的结果?

发布于 2024-12-10 15:44:22 字数 6336 浏览 0 评论 0原文

我正在制作一个用于计算金钱的应用程序,并且读到最好使用 NSNumber 来实现这一点。所以我已将浮点值更改为 NSNumber 但现在我得到以下奇怪的结果,我不知道为什么会发生。

这是代码:

- (NSDecimalNumber*) subtotal {
    NSDecimalNumber *subtotal = [NSDecimalNumber decimalNumberWithString:@"0"];
    NSLog(@"subtotal initially set at %@",subtotal);
    for (NSManagedObject *object in [fetchedResultsController fetchedObjects]) {
        NSLog( @"Looping");
        NSDecimalNumber *objectRowTotalNumber = [object valueForKey:@"total"];
        NSLog(@"object row total number = %@",objectRowTotalNumber);
        subtotal = [subtotal decimalNumberByAdding:objectRowTotalNumber];

        NSLog(@"Subtotal: %@", subtotal);
    }

    return 0;
}

这是日志中的输出:

**2011-10-19 09:27:19.289 Market[4240:b603] subtotal initially set at 0**

**2011-10-19 09:27:19.290 Market[4240:b603] Looping**

**2011-10-19 09:27:19.291 Market[4240:b603] object row total number = 5**

**2011-10-19 09:27:19.292 Market[4240:b603] Subtotal: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000244200806570181766106054656**

当小计应该简单设置为 5 时,有人知道是什么导致了奇怪的结果吗?

最新测试: NSDecimalNumberMethod 仅适用于我在会话中添加的新对象,但不适用于加载的对象

-(void) viewDidAppear:(BOOL)animated {
NSLog(@"I'm in ViewDidAppear");
// Reload subtotal via float method
[self subtotal];
//Reload subtotal via decimal method
[self subtotalDec];
}

使用 float 方法

-(float) subtotal {
NSLog(@"I'm in subtotal using floats");

float subtotal = 0;
NSLog(@"subtotal initially set at %@",subtotal);
for (NSManagedObject *object in [fetchedResultsController fetchedObjects]) {
NSLog( @"Looping");
NSNumber *objectRowTotalNumber = [object valueForKey:@"total"];
NSLog(@"object row total number = %@",objectRowTotalNumber);
float objectRowTotal = [objectRowTotalNumber floatValue];
subtotal = subtotal + objectRowTotal;
}
NSLog(@"Subtotal: %f", subtotal);
return 0;
}

计算 使用 NSDecimal Number Method

- (NSDecimalNumber*) subtotalDec {
NSLog(@"I'm in subtotal using NSDecimalNumber");
NSDecimalNumber *subtotal = [NSDecimalNumber decimalNumberWithString:@"0"];
NSLog(@"subtotal initially set at %@",subtotal);
for (NSManagedObject *object in [fetchedResultsController fetchedObjects]) {
NSLog( @"Looping");
NSDecimalNumber *objectRowTotalNumber = [object valueForKey:@"total"];
NSLog(@"object row total number = %@",objectRowTotalNumber);
subtotal = [subtotal decimalNumberByAdding:objectRowTotalNumber];
}
NSLog(@"Subtotal: %@",subtotal);
return 0;
}

日志进行查看 将显示

2011-10-19 11:19:01.506 Market[961:b603] I'm in ViewDidAppear
2011-10-19 11:19:01.506 Market[961:b603] I'm in subtotal using floats
2011-10-19 11:19:01.507 Market[961:b603] subtotal initially set at (null)
2011-10-19 11:19:01.508 Market[961:b603] Looping
2011-10-19 11:19:01.508 Market[961:b603] object row total number = 4
2011-10-19 11:19:01.509 Market[961:b603] Looping
2011-10-19 11:19:01.509 Market[961:b603] object row total number = 1
2011-10-19 11:19:01.509 Market[961:b603] Looping
2011-10-19 11:19:01.510 Market[961:b603] object row total number = 10
2011-10-19 11:19:01.510 Market[961:b603] Subtotal: 15.000000
2011-10-19 11:19:01.510 Market[961:b603] I'm in subtotal using NSDecimalNumber
2011-10-19 11:19:01.511 Market[961:b603] subtotal initially set at 0   
2011-10-19 11:19:01.511 Market[961:b603] Looping
2011-10-19 11:19:01.511 Market[961:b603] object row total number = 4
2011-10-19 11:19:01.512 Market[961:b603] Subtotal: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000244200806569055866199212032
2011-10-19 11:19:01.512 Market[961:b603] Looping
2011-10-19 11:19:01.512 Market[961:b603] object row total number = 1
2011-10-19 11:19:01.513 Market[961:b603] Subtotal: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000488401613129104533143683072
2011-10-19 11:19:01.513 Market[961:b603] Looping
2011-10-19 11:19:01.513 Market[961:b603] object row total number = 10
2011-10-19 11:19:01.514 Market[961:b603] Subtotal: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000732602419703789898877108224

addbuttontapped 日志: 注意NSDecimalNumberMethod 如何仅适用于最后添加的值,而不适用于程序启动前输入的值

2011-10-20 07:17:03.218 Market[2199:b603] I'm in subtotal using floats
2011-10-20 07:17:03.218 Market[2199:b603] subtotal initially set at (null)
2011-10-20 07:17:03.219 Market[2199:b603] Looping
2011-10-20 07:17:03.219 Market[2199:b603] object row total number = 4
2011-10-20 07:17:03.219 Market[2199:b603] Looping
2011-10-20 07:17:03.219 Market[2199:b603] object row total number = 1
2011-10-20 07:17:03.220 Market[2199:b603] Looping
2011-10-20 07:17:03.220 Market[2199:b603] object row total number = 10
2011-10-20 07:17:03.220 Market[2199:b603] Looping
2011-10-20 07:17:03.221 Market[2199:b603] object row total number = 2
2011-10-20 07:17:03.221 Market[2199:b603] Subtotal: 17.000000
2011-10-20 07:17:03.221 Market[2199:b603] I'm in subtotal using NSDecimalNumber
2011-10-20 07:17:03.222 Market[2199:b603] subtotal initially set at 0
2011-10-20 07:17:03.222 Market[2199:b603] Looping
2011-10-20 07:17:03.222 Market[2199:b603] object row total number = 4
2011-10-20 07:17:03.223 Market[2199:b603] Subtotal: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000244200806569055866199212032
2011-10-20 07:17:03.223 Market[2199:b603] Looping
2011-10-20 07:17:03.224 Market[2199:b603] object row total number = 1
2011-10-20 07:17:03.224 Market[2199:b603] Subtotal: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000488401613129104533143683072
2011-10-20 07:17:03.224 Market[2199:b603] Looping
2011-10-20 07:17:03.225 Market[2199:b603] object row total number = 10
2011-10-20 07:17:03.225 Market[2199:b603] Subtotal: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000732602419703789898877108224
2011-10-20 07:17:03.225 Market[2199:b603] Looping
2011-10-20 07:17:03.226 Market[2199:b603] object row total number = 2
2011-10-20 07:17:03.226 Market[2199:b603] Subtotal: 2

I am making an app that deals with calculating money and have read that its always best to use NSNumber for this. So I have changed my float values to NSNumber but now I get the following odd result and I don't know why it is occurring.

This is the code:

- (NSDecimalNumber*) subtotal {
    NSDecimalNumber *subtotal = [NSDecimalNumber decimalNumberWithString:@"0"];
    NSLog(@"subtotal initially set at %@",subtotal);
    for (NSManagedObject *object in [fetchedResultsController fetchedObjects]) {
        NSLog( @"Looping");
        NSDecimalNumber *objectRowTotalNumber = [object valueForKey:@"total"];
        NSLog(@"object row total number = %@",objectRowTotalNumber);
        subtotal = [subtotal decimalNumberByAdding:objectRowTotalNumber];

        NSLog(@"Subtotal: %@", subtotal);
    }

    return 0;
}

This is the output in the log:

**2011-10-19 09:27:19.289 Market[4240:b603] subtotal initially set at 0**

**2011-10-19 09:27:19.290 Market[4240:b603] Looping**

**2011-10-19 09:27:19.291 Market[4240:b603] object row total number = 5**

**2011-10-19 09:27:19.292 Market[4240:b603] Subtotal: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000244200806570181766106054656**

Would anyone know what is causing the odd result when the subtotal should simple be set to 5?

Latest Test : The NSDecimalNumberMethod works only on new objects that I add in the session, but not on objects that are loaded

-(void) viewDidAppear:(BOOL)animated {
NSLog(@"I'm in ViewDidAppear");
// Reload subtotal via float method
[self subtotal];
//Reload subtotal via decimal method
[self subtotalDec];
}

Calculating with float method

-(float) subtotal {
NSLog(@"I'm in subtotal using floats");

float subtotal = 0;
NSLog(@"subtotal initially set at %@",subtotal);
for (NSManagedObject *object in [fetchedResultsController fetchedObjects]) {
NSLog( @"Looping");
NSNumber *objectRowTotalNumber = [object valueForKey:@"total"];
NSLog(@"object row total number = %@",objectRowTotalNumber);
float objectRowTotal = [objectRowTotalNumber floatValue];
subtotal = subtotal + objectRowTotal;
}
NSLog(@"Subtotal: %f", subtotal);
return 0;
}

Calculating with NSDecimal Number Method

- (NSDecimalNumber*) subtotalDec {
NSLog(@"I'm in subtotal using NSDecimalNumber");
NSDecimalNumber *subtotal = [NSDecimalNumber decimalNumberWithString:@"0"];
NSLog(@"subtotal initially set at %@",subtotal);
for (NSManagedObject *object in [fetchedResultsController fetchedObjects]) {
NSLog( @"Looping");
NSDecimalNumber *objectRowTotalNumber = [object valueForKey:@"total"];
NSLog(@"object row total number = %@",objectRowTotalNumber);
subtotal = [subtotal decimalNumberByAdding:objectRowTotalNumber];
}
NSLog(@"Subtotal: %@",subtotal);
return 0;
}

log for view Will appear

2011-10-19 11:19:01.506 Market[961:b603] I'm in ViewDidAppear
2011-10-19 11:19:01.506 Market[961:b603] I'm in subtotal using floats
2011-10-19 11:19:01.507 Market[961:b603] subtotal initially set at (null)
2011-10-19 11:19:01.508 Market[961:b603] Looping
2011-10-19 11:19:01.508 Market[961:b603] object row total number = 4
2011-10-19 11:19:01.509 Market[961:b603] Looping
2011-10-19 11:19:01.509 Market[961:b603] object row total number = 1
2011-10-19 11:19:01.509 Market[961:b603] Looping
2011-10-19 11:19:01.510 Market[961:b603] object row total number = 10
2011-10-19 11:19:01.510 Market[961:b603] Subtotal: 15.000000
2011-10-19 11:19:01.510 Market[961:b603] I'm in subtotal using NSDecimalNumber
2011-10-19 11:19:01.511 Market[961:b603] subtotal initially set at 0   
2011-10-19 11:19:01.511 Market[961:b603] Looping
2011-10-19 11:19:01.511 Market[961:b603] object row total number = 4
2011-10-19 11:19:01.512 Market[961:b603] Subtotal: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000244200806569055866199212032
2011-10-19 11:19:01.512 Market[961:b603] Looping
2011-10-19 11:19:01.512 Market[961:b603] object row total number = 1
2011-10-19 11:19:01.513 Market[961:b603] Subtotal: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000488401613129104533143683072
2011-10-19 11:19:01.513 Market[961:b603] Looping
2011-10-19 11:19:01.513 Market[961:b603] object row total number = 10
2011-10-19 11:19:01.514 Market[961:b603] Subtotal: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000732602419703789898877108224

log for addbuttontapped: Notice how the NSDecimalNumberMethod works only on the last added value, not on the ones that were entered before the program was started

2011-10-20 07:17:03.218 Market[2199:b603] I'm in subtotal using floats
2011-10-20 07:17:03.218 Market[2199:b603] subtotal initially set at (null)
2011-10-20 07:17:03.219 Market[2199:b603] Looping
2011-10-20 07:17:03.219 Market[2199:b603] object row total number = 4
2011-10-20 07:17:03.219 Market[2199:b603] Looping
2011-10-20 07:17:03.219 Market[2199:b603] object row total number = 1
2011-10-20 07:17:03.220 Market[2199:b603] Looping
2011-10-20 07:17:03.220 Market[2199:b603] object row total number = 10
2011-10-20 07:17:03.220 Market[2199:b603] Looping
2011-10-20 07:17:03.221 Market[2199:b603] object row total number = 2
2011-10-20 07:17:03.221 Market[2199:b603] Subtotal: 17.000000
2011-10-20 07:17:03.221 Market[2199:b603] I'm in subtotal using NSDecimalNumber
2011-10-20 07:17:03.222 Market[2199:b603] subtotal initially set at 0
2011-10-20 07:17:03.222 Market[2199:b603] Looping
2011-10-20 07:17:03.222 Market[2199:b603] object row total number = 4
2011-10-20 07:17:03.223 Market[2199:b603] Subtotal: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000244200806569055866199212032
2011-10-20 07:17:03.223 Market[2199:b603] Looping
2011-10-20 07:17:03.224 Market[2199:b603] object row total number = 1
2011-10-20 07:17:03.224 Market[2199:b603] Subtotal: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000488401613129104533143683072
2011-10-20 07:17:03.224 Market[2199:b603] Looping
2011-10-20 07:17:03.225 Market[2199:b603] object row total number = 10
2011-10-20 07:17:03.225 Market[2199:b603] Subtotal: -0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000732602419703789898877108224
2011-10-20 07:17:03.225 Market[2199:b603] Looping
2011-10-20 07:17:03.226 Market[2199:b603] object row total number = 2
2011-10-20 07:17:03.226 Market[2199:b603] Subtotal: 2

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

铜锣湾横着走 2024-12-17 15:44:22

我不认为 [object valueForKey:@"total"] 会返回一个 NSDecimalNumber,而是返回一个 NSNumber

更新:

显然这正朝着正确的方向发展。因此,请取消删除该帖子,以便我们能够正确回答问题。

我删除了这个,因为写完后,我尝试使用 NSNumber 来 decimalNumberByAdding: ,然后它崩溃了。但这是在 OSX 10.7 SDK 项目中,因此显然在 iOS 中处理方式有所不同。

I don't think [object valueForKey:@"total"] is giving you back an NSDecimalNumber, but rather an NSNumber.

Update:

Apparently this was going in the right direction. Therefore, undelete the post, so we can have a properly answered question.

I deleted this, because after writing it, I tried decimalNumberByAdding: with an NSNumber, and it crashed. But this was in a OSX 10.7 SDK project, so apparently this gets handled differently in iOS.

绝對不後悔。 2024-12-17 15:44:22

为了让它工作,我必须在代码中添加两行。这是我必须做的。

- (NSDecimalNumber*) subtotalDec {
NSLog(@"I'm in subtotal using NSDecimalNumber");
NSDecimalNumber *subtotal = [NSDecimalNumber decimalNumberWithString:@"0"];
NSLog(@"subtotal initially set at %@",subtotal);
for (NSManagedObject *object in [fetchedResultsController fetchedObjects]) {
NSLog( @"Looping");
NSDecimalNumber *objectRowTotalNumber = [object valueForKey:@"total"];
NSLog(@"object row total number = %@",objectRowTotalNumber);
//This is the start of added code
NSString *objectRowString = [NSString stringWithFormat:@"%@",objectRowTotalNumber];
NSDecimalNumber *objectRowTotal = [NSDecimalNumber    decimalNumberWithString:objectRowString];
//This is the end of added code
subtotal = [subtotal decimalNumberByAdding:objectRowTotal];

NSLog(@"Subtotal: %@",subtotal);

}

In order to get it to work I had to add two lines to the code. This is what I had to do.

- (NSDecimalNumber*) subtotalDec {
NSLog(@"I'm in subtotal using NSDecimalNumber");
NSDecimalNumber *subtotal = [NSDecimalNumber decimalNumberWithString:@"0"];
NSLog(@"subtotal initially set at %@",subtotal);
for (NSManagedObject *object in [fetchedResultsController fetchedObjects]) {
NSLog( @"Looping");
NSDecimalNumber *objectRowTotalNumber = [object valueForKey:@"total"];
NSLog(@"object row total number = %@",objectRowTotalNumber);
//This is the start of added code
NSString *objectRowString = [NSString stringWithFormat:@"%@",objectRowTotalNumber];
NSDecimalNumber *objectRowTotal = [NSDecimalNumber    decimalNumberWithString:objectRowString];
//This is the end of added code
subtotal = [subtotal decimalNumberByAdding:objectRowTotal];

NSLog(@"Subtotal: %@",subtotal);

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文