Consider this code:
NSNumber* interchangeId = dict[@\"interchangeMarkerLogId\"];
long long llValue = [interchangeId longLongValue];
double dValue = [intercha
As documented in NSDecimalNumber.h, NSDecimalNumber always returns "d" for it's return type. This is expected behavior.
- (const char *)objCType NS_RETURNS_INNER_POINTER;
// return 'd' for double
And also in the Developer Docs:
Returns a C string containing the Objective-C type of the data contained in the
receiver, which for an NSDecimalNumber object is always “d” (for double).
CFNumberGetValue is documented to return false if the conversion was lossy. In the event of a lossy conversion, or when you encounter an NSDecimalNumber, you will want to fall back to using the stringValue and then use sqlite3_bind_text to bind it (and use sqlite's column affinity).
Something like this:
NSNumber *number = ...
BOOL ok = NO;
if (![number isKindOfClass:[NSDecimalNumber class]]) {
CFNumberType numberType = CFNumberGetType(number);
if (numberType == kCFNumberFloat32Type ||
numberType == kCFNumberFloat64Type ||
numberType == kCFNumberCGFloatType)
{
double value;
ok = CFNumberGetValue(number, kCFNumberFloat64Type, &value);
if (ok) {
ok = (sqlite3_bind_double(pStmt, idx, value) == SQLITE_OK);
}
} else {
SInt64 value;
ok = CFNumberGetValue(number, kCFNumberSInt64Type, &value);
if (ok) {
ok = (sqlite3_bind_int64(pStmt, idx, value) == SQLITE_OK);
}
}
}
// We had an NSDecimalNumber, or the conversion via CFNumberGetValue() was lossy.
if (!ok) {
NSString *stringValue = [number stringValue];
ok = (sqlite3_bind_text(pStmt, idx, [stringValue UTF8String], -1, SQLITE_TRANSIENT) == SQLITE_OK);
}