Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Модуль JSON преобразует числа


Автор: cyberblade 18.5.2019, 16:38
Может я сам туплю или чего-то не понимаю... Использую модуль со CPAN - JSON
мне в ответе от сервера может прилетать значение с множеством нулей после запятой, например 0.000000001
до того как я начинаю парсить ответ сервера, число с плавающей точкой, после парсинга он его преобразует в целое (видимо для оптимизации): 1e-008

как можно отключить это кто-нить в курсе? Т. к. в разных полях могут приходить совершенно разные числа. 

Т. е. мне нужно сохранить оригинальный формат числа.

Код

#!\usr\bin\perl -w


use strict;
use warnings;

# use modules
use LWP::UserAgent;
use JSON;
use Data::Dumper;
use DateTime;

# vars
my $url = 'xxx';

    my $ua = LWP::UserAgent->new(timeout => 10);
    $ua->agent('Mozilla/5.0');
    $ua->env_proxy;

    my $response = $ua->get($url);

    my $j = decode_json $response->decoded_content;



Спасибо за помощь. 

Автор: arto 20.5.2019, 07:32
1. 1e-008 - не целое
2. 1е-008 !=  0.000000001
3. покажите данные

Автор: cyberblade 20.5.2019, 10:45
Вот полный листинг программы вместе с тестируемым урлом.
Код

#!\usr\bin\perl -w


use strict;
use warnings;

# use modules
use JSON;
use LWP::UserAgent;
use Data::Dumper;
use DateTime;

# my $dt = DateTime->from_epoch( epoch => $epoch );
# $dt->set_time_zone( 'Asia/Yekaterinburg' );

# vars
my $url = 'https://yobit.net/api/3/info';

# start
my $json = geturl($url);

# write test file (res)
open(F,">test.txt");
print F Dumper($json);
close(F);

# subs 

sub geturl {

    # take url link
    my $url = shift;

    # use lwp
    my $ua = LWP::UserAgent->new(timeout => 10);
    $ua->agent('Mozilla/5.0');
    $ua->env_proxy;

    # get requset     
    my $response = $ua->get($url);
     
    # response
    if ($response->is_success) {
        return decode_json $response->decoded_content;
    }
    # error message
    else { die $response->status_line; return $response->status_line;}
}



Вот такие данные выдаёт api биржи 
"min_price":0.00000001,"

Вот так они сохраняются после парсинга JSON
'min_price' => '1e-008',

Автор: arto 20.5.2019, 11:16
1. 0.00000001 и 1e-008, просто разная нотация:
# perl -e 'printf "%e %.8f\n", 0.00000001, 0.00000001' 
1.000000e-08
0.00000001
2. perldoc JSON
...
    number
        A JSON number becomes either an integer, numeric (floating point) or
        string scalar in perl, depending on its range and any fractional
        parts. On the Perl level, there is no difference between those as
        Perl handles all the conversion details, but an integer may take
        slightly less memory and might represent more values exactly than
        floating point numbers.

        If the number consists of digits only, this module will try to
        represent it as an integer value. If that fails, it will try to
        represent it as a numeric (floating point) value if that is possible
        without loss of precision. Otherwise it will preserve the number as
        a string value (in which case you lose roundtripping ability, as the
        JSON number will be re-encoded to a JSON string).
...

Автор: cyberblade 20.5.2019, 12:11
Ну я об этом в курсе, спасибо за попытку помочь... 

Вопрос в другом был, есть ли возможность вообще отключить это без бубна? Без разницы как будут приходить данные хоть в строковом, хоть в числовом значении.
Ибо JSON формат будет разный и прогонять определенные хеши через printf при выводе мягко говоря не очень правильный вариант. Кроме того это дополнительное процессорное время. Учитывая что такой хеш может быть размером более 20 мб. 

Ну и собственно я вам и говорил что JSON просто пытается конвертировать представление с плавающей запятой в целое значение если это возможно. Я читал этот мануал. 
Ибо в машинном представлении 1e-008 - это целое, но вы видите его разумеется как не целое ))

Или может есть какие-то другие нормальные модули, которые без своевольностей работают? =) 
Буду благодарен за подсказку

Автор: arto 21.5.2019, 06:25
могу порекомендовать либо filter_json_single_key_object, либо ковырять сам модуль.

Добавлено через 1 минуту и 54 секунды
могу порекомендовать либо filter_json_single_key_object, либо править сам модуль.

Автор: cyberblade 21.5.2019, 13:13
Спасибо, гляну

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)