Integer.parseInt большое число и сохранить знак?

Я работаю с шестнадцатеричными значениями, и мне нужно сохранить знак значений. Мне интересно, есть ли у кого-нибудь творческий способ сохранить знак int без использования BigInteger? Я не могу использовать BigInteger, потому что его нет в моей библиотеке из-за ограничений по размеру; моя программа работает во встроенной среде.

У меня есть строка шестнадцатеричных значений следующим образом: 55844d000000000080027d801cf6380006f416c0c23d3e4000000000

    String          ssumI = null;
    String          ssumQ = null;
    String          sazI   = null;
    float           isumI = 0;
    float           isumQ = 0;
    float           iazI  = 0;

    ssumI = data.substring(0,8); 
    isumI = (float)(Integer.parseInt(ssumI, 16)/Math.pow(2,bits));
    //55844d00 parses fine

    ssumQ = data.substring(8,16); 
    isumQ = (float)(Integer.parseInt(ssumQ, 16)/Math.pow(2,bits));
    //00000000 parses fine

    sazI = data.substring(16, 24); 
    iazI = (float)(Integer.parseInt(sazI, 16)/Math.pow(2,bits));
    //80027d80 fails - NumberFormatException
    //should be -1,036,173,760 and in the int range

Я не правильно понимаю неисправность? Похоже, что сбой связан с установленным битом знака.


person txcotrader    schedule 20.03.2015    source источник
comment
Очевидным решением здесь является BigInteger, так почему бы вам его не использовать?   -  person Jon Skeet    schedule 20.03.2015
comment
Его нет в моей библиотеке из-за ограничений по размеру, моя программа работает во встроенной среде.   -  person txcotrader    schedule 20.03.2015
comment
Правильно, поэтому вы должны указать это в своем вопросе. Каждый раз, когда очевидное решение не подходит, потому что вы находитесь в необычном контексте, вы должны объяснить этот контекст.   -  person Jon Skeet    schedule 20.03.2015
comment
если биты не являются значением с плавающей запятой или больше 31, используйте 1 << bits вместо Math.pow(2,bits)   -  person phuclv    schedule 20.03.2015


Ответы (2)


Если вы хотите хранить 32 бита за раз, очевидным решением, на мой взгляд, будет вместо этого анализировать с помощью Long.parseLong:

isumI = (float)(Long.parseLong(ssumI, 16) / Math.pow(2, bits));

(Вы определенно хотите сохранить эти значения как float? Таким образом вы теряете информацию...)

person Jon Skeet    schedule 20.03.2015

Если доступна Java 8, вы можете использовать в ней новые неподписанные операции (Как использовать целое число без знака в Java 8?).

isumI = (float)(Integer.parseUnsignedInt(ssumI, 16)/Math.pow(2,bits));

Но поскольку каждая строка имеет 32 бита, я полагаю, что bits меньше 32. В этом случае вы можете переписать ее как

isumI = Integer.parseUnsignedInt(ssumI, 16)/(float)(1 << bits);

Если bits может быть больше 32 (но меньше 64), замените 1 на 1L

Кроме того, обратите внимание, что биты в вашей функции не изменились, вы должны заменить Math.pow(2, bits) на 1 << bits и сохранить его в отдельной переменной вместо того, чтобы пересчитывать его снова и снова.

В любом случае, если вы собираетесь использовать строку как большое значение, вам следует сохранить ее в массиве int. float имеет только 24 значащих бита, и вы можете потерять младшие 8 бит, если значение велико.

person phuclv    schedule 20.03.2015