Значение NSNumber изменяется, когда объект JSON преобразуется в данные, а затем эти данные снова преобразуются обратно в объект JSON. - PullRequest
0 голосов
/ 08 мая 2018

Я создаю NSData объект со словарем следующим образом,

словарь

{
    channelId = 201;
    lang = EN;
    reqRefNo = vZRIzNd;
    storeInfo =     {
        clientInfo =         {
            deviceId = XXXXXXXXA67F488B836D19D80EC4FD8D;
        };
        loginLogId = XXXXXXXX5CAD4A0DA06BE2F055929856;
        qrCodeInfo =         {
            itemDesc = "";
            itemName = hahsj;
            price = 106;
        };
        userInfo =         {
            storeId = 3252;
        };
    };
}

цена = 106

NSData *data = [NSJSONSerialization dataWithJSONObject:paramDict options:kNilOptions error:nil];

Теперь я снова преобразовываю его обратно в объект JSON следующим образом:

NSDictionary* json = [NSJSONSerialization JSONObjectWithData:data
                                                         options:kNilOptions
                                                       error:&error];

Но на этот раз я получаю неправильную цену.

преобразованный словарь

{
    channelId = 201;
    lang = EN;
    reqRefNo = vZRIzNd;
    storeInfo =     {
        clientInfo =         {
            deviceId = XXXXXXXXA67F488B836D19D80EC4FD8D;
        };
        loginLogId = XXXXXXXX5CAD4A0DA06BE2F055929856;
        qrCodeInfo =         {
            itemDesc = "";
            itemName = hahsj;
            price = "105.9999923706055";
        };
        userInfo =         {
            storeId = 3252;
        };
    };
}

цена = "105.9999923706055"

Код для генерации NSNumber,

//_amountTF.text = "S$1.06";
NSString *amount = [_amountTF.text stringByReplacingOccurrencesOfString:@"S$" withString:@""];
float amt = [amount floatValue];
amt *=100;
NSNumber *num = [NSNumber numberWithFloat:amt];

Может кто-нибудь объяснить мне причину этого? Спасибо.

1 Ответ

0 голосов
/ 08 мая 2018

Это проблема точности с плавающей запятой. Используйте double вместо float.

Ваше число хранится в двоичном формате, который не может точно представлять все десятичные значения, поэтому некоторые значения «округляются» до ближайшего двоичного значения. При печати числа, он сначала преобразует число с плавающей запятой в двойное, а затем печатает его. Преобразование в двойное будет принимать ваше округленное двоичное представление и хранить с более высокой точностью, делая его высокой точностью с низким содержанием контента в нем. Распечатка покажет приблизительное значение, полученное при использовании точности с плавающей точкой.

NSString *amount = [_amountTF.text stringByReplacingOccurrencesOfString:@"S$" withString:@""];
double amt = [amount doubleValue];
amt *=100;
NSNumber *num = [NSNumber numberWithDouble:amt];

Подробнее: «плавание» против «двойной» точности

...