简体   繁体   中英

float value changes when passed to a method in objective-c

Ok here goes my situation:

I have a core-data generated class Quantity which has one of its attributes 'Value', marked as a float.

There's a convenience method in the Quantity class which helps me set this property:

- (void)setValueValue:(float)value_ {

    [self setValue:[NSNumber numberWithFloat:value_]];

}

Now when I set try set this value from a Controller like this,

Quantity *q = (Quantity *) [NSEntityDescription insertNewObjectForEntityForName:@"Quantity" inManagedObjectContext:self.managedObjectContext];

float qv = 100.0f;

[q setValueValue:qv];

the value gets set as 1.40129846e-43

I put breakpoints in both locations above, and while the tooltip correctly shows the value as 100.0 in the Controller class, it shows the incorrect value in the setter method.

And ultimately, the value that gets stored in the object and the db is the incorrect value.

Any clues as to what's happening here??

1.40129846e-43 is a very interesting number, and tells us what's happening here.

Specifically:

1.40129846e-43 = 100 * 2^-149

More simply, the value that you're observing is what you get if you interpret the integer value 100 as the encoding of a float .

What is most likely happening is that you haven't included the header that declares the setValueValue:(float) method, or that the declaration is otherwise not in scope at the location from which you are calling the method. This results in the compiler assuming that the method takes an integer argument instead of a floating-point argument.

Thus, the caller converts your 100.f value into the integer 100 , which is then interpreted by the function as the encoding of the floating-point number you are observing.

The other possibility is that a similar type impedance mismatch is happening somewhere in your logging code.

TLDR: make sure you declare your functions before you use them in C-based languages.

There is nothing wrong with the code you posted beyond the possibility of a naming collision. The dynamic accessor will have the name setValue: so setValueValue: runs the risk of confusing the runtime.

However, most likely, you are looking at a logging error ie the data is fine you are just displaying it incorrectly. If you use an NSLog with the wrong type in the format you will get very large, nonsensical outputs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM