2009-07-24 20 views
6

Tôi bị nhầm lẫn bởi NSDecimalNumber và "hành vi" của nó. Tôi có một NSDecimalNumber đại diện cho một giá trị đô la, nói $ 37,50. Tôi muốn tìm hiểu bao nhiêu lần nói 5.0 đi vào con số đó và sau đó biết những gì còn lại. Tôi có thể nhận được các bộ phận thẳng và nhận được 7,50 nhưng tôi muốn 7 mod 2,50. Tôi có thể chuyển đổi thành một số nguyên nhưng cần phải lưu "xu" để tự hỏi nếu có một số thủ thuật trong khuôn khổ?Làm thế nào để bạn có được int và modulo (mod) của bộ phận với một NSDecimalNumber

Trả lời

1

Về mặt lý thuyết, bạn có thể thực hiện một số thủ thuật với các phương pháp NSDecimalNumber decimalNumberByDividingBy:, decimalNumberByMultiplyingBy:decimalValue. Chia các số, lấy cấu trúc số thập phân, tìm ra phần còn lại từ cấu trúc, sau đó tạo số thập phân mới với số còn lại và nhân số còn lại với số ban đầu. Tuy nhiên, cách dễ dàng hơn để có thể xác định độ chính xác tối đa mà bạn muốn (gọi là N vị trí sau dấu thập phân), nhân số với 10eN, sau đó chỉ lấy giá trị nguyên và làm phân chia và sửa đổi điều đó. Bạn chạy nguy cơ mất dữ liệu, đặc biệt là với số lượng rất lớn, tuy nhiên, vì vậy hãy kiểm tra số lớn nhất bạn muốn và tìm ra loại dữ liệu nào - nếu có - sẽ làm việc cho bạn. NSNumber hỗ trợ unsignedLongLongValue.

4
  1. Chia cổ tức bằng số chia, làm tròn xuống. Điều này giúp bạn có được thương.
  2. Nhân số chia cho thương.
  3. Trừ từ cổ tức. Điều này giúp bạn phần còn lại.

(37.50 // 5) == 7; 7 * 5 == 35; 37,50 - 35 = 2,50.

(Lưu ý:... // là nhà điều hành của Python cho bộ phận không thể thiếu tôi đã mượn nó ở đây Rõ ràng, bạn không nên thực sự cố gắng sử dụng // cho bộ phận trong mã Objective-C)

+0

Để làm tròn xuống, sử dụng floor() từ math.h - nó sẽ tăng gấp đôi và trả về gấp đôi. –

+0

Nếu bạn đang sử dụng số thập phân, hãy cố gắng ở trong loại đó càng nhiều càng tốt. Cụ thể là, để sử dụng vòng decimalNumberByRoundingAccordingToBehavior :. – Tim

+0

Tốt hơn, hãy sử dụng 'decimalNumberByDividingBy: withBehavior:' để thực hiện phép chia. Sau đó, bạn không cần phải tròn riêng biệt. –

6

Sử dụng Peter Hoseys dụ, nhưng với mã iOS:

NSDecimalNumber *dividend = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithDouble:37.5] decimalValue]]; 

NSDecimalNumber *divisor = [NSDecimalNumber decimalNumberWithDecimal:[[NSNumber numberWithDouble:5.0] decimalValue]]; 

NSDecimalNumber *quotient = [dividend decimalNumberByDividingBy:divisor withBehavior:[NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:NSRoundDown scale:0 raiseOnExactness:NO raiseOnOverflow:NO raiseOnUnderflow:NO raiseOnDivideByZero:NO]]; 

NSDecimalNumber *subtractAmount = [quotient decimalNumberByMultiplyingBy:divisor]; 

NSDecimalNumber *remainder = [dividend decimalNumberBySubtracting:subtractAmount]; 
+0

Bạn phải đặt chế độ làm tròn phù hợp nếu một trong số cổ tức hoặc số chia là số âm. 'NSRoundingMode roundingMode = ((cổ tức.floatValue <0)^(divisor.floatValue <0))? NSRoundUp: NSRoundDown; ' – user500

5

Dưới đây là một thể loại NSDecimalNumber mà cũng làm việc với những con số tiêu cực và ước tiêu cực:

- (BOOL)isNegative 
{ 
    return (NSOrderedDescending == [[NSDecimalNumber zero] compare:self]); 
} 

- (NSDecimalNumber *)invertedNumber 
{ 
    NSDecimalNumber *negOne = [NSDecimalNumber decimalNumberWithMantissa:1 exponent:0 isNegative:YES]; 
    return [self decimalNumberByMultiplyingBy:negOne]; 
} 

- (NSDecimalNumber *)moduloFor:(NSDecimalNumber *)divisor 
{ 
    NSRoundingMode roundingMode = ([self isNegative]^[divisor isNegative]) ? NSRoundUp : NSRoundDown; 
    NSDecimalNumberHandler *rounding = [NSDecimalNumberHandler decimalNumberHandlerWithRoundingMode:roundingMode 
                           scale:0 
                        raiseOnExactness:NO 
                        raiseOnOverflow:NO 
                        raiseOnUnderflow:NO 
                       raiseOnDivideByZero:NO]; 

    // divide and get the remainder 
    NSDecimalNumber *quotient = [self decimalNumberByDividingBy:divisor withBehavior:rounding]; 
    NSDecimalNumber *subtract = [quotient decimalNumberByMultiplyingBy:divisor]; 

    NSDecimalNumber *modulo = [self decimalNumberBySubtracting:subtract]; 
    if ([divisor isNegative]) { 
     return [modulo invertedNumber]; 
    } 
    return modulo; 
} 
Các vấn đề liên quan