java整形转二进制_在Java卡中将整数的二进制表示形式转换为...

这比您想象的要棘手,因为它需要基数转换,并且基数转换使用大整数算法在整数上执行.

当然,这并不意味着我们不能为此目的专门创建上述大整数算法的有效实现.这是一种将零填充(通常在Java卡上是必需的)而不使用额外内存(!)的实现.但是,如果要保留大端数字,则可能必须复制其原始值-输入值将被覆盖.强烈建议将其放入RAM.

这段代码简单地将字节除以新的基数(十进制为10),返回余数.其余为下一个最低位数.由于输入值现在已经被除,下一个余数就是仅比前一个有效位高一位的数字.它将继续除法并返回余数,直到该值为零并且计算完成.

该算法的棘手部分是内部循环,该循环将值除以10后就位,同时使用尾数除以字节来返回余数.每次运行可提供一个余数/十进制数字.这也意味着函数的顺序为O(n),其中n是结果中的位数(将尾部除法定义为单个操作).请注意,n可以通过ceil(bigNumBytes * log_10(256))计算:其结果也存在于预先计算的BCD_SIZE_PER_BYTES表中. log_10(256)当然是一个恒定的十进制值,高于2.408.

这是经过优化的最终代码(请参见不同版本的编辑内容):

/**

* Converts an unsigned big endian value within the buffer to the same value

* stored using ASCII digits. The ASCII digits may be zero padded, depending

* on the value within the buffer.

*

* Warning: this method zeros the value in the buffer that

* contains the original number. It is strongly recommended that the input

* value is in fast transient memory as it will be overwritten multiple

* times - until it is all zero.

*

*

* Warning: this method fails if not enough bytes are

* available in the output BCD buffer while destroying the input buffer.

*

*

* Warning: the big endian number can only occupy 16 bytes

* or less for this implementation.

*

*

* @param uBigBuf

* the buffer containing the unsigned big endian number

* @param uBigOff

* the offset of the unsigned big endian number in the buffer

* @param uBigLen

* the length of the unsigned big endian number in the buffer

* @param decBuf

* the buffer that is to receive the BCD encoded number

* @param decOff

* the offset in the buffer to receive the BCD encoded number

* @return decLen, the length in the buffer of the received BCD encoded

* number

*/

public static short toDecimalASCII(byte[] uBigBuf, short uBigOff,

short uBigLen, byte[] decBuf, short decOff) {

// variables required to perform long division by 10 over bytes

// possible optimization: reuse remainder for dividend (yuk!)

short dividend, division, remainder;

// calculate stuff outside of loop

final short uBigEnd = (short) (uBigOff + uBigLen);

final short decDigits = BYTES_TO_DECIMAL_SIZE[uBigLen];

// --- basically perform division by 10 in a loop, storing the remainder

// traverse from right (least significant) to the left for the decimals

for (short decIndex = (short) (decOff + decDigits - 1); decIndex >= decOff; decIndex--) {

// --- the following code performs tail division by 10 over bytes

// clear remainder at the start of the division

remainder = 0;

// traverse from left (most significant) to the right for the input

for (short uBigIndex = uBigOff; uBigIndex < uBigEnd; uBigIndex++) {

// get rest of previous result times 256 (bytes are base 256)

// ... and add next positive byte value

// optimization: doing shift by 8 positions instead of mul.

dividend = (short) ((remainder << 8) + (uBigBuf[uBigIndex] & 0xFF));

// do the division

division = (short) (dividend / 10);

// optimization: perform the modular calculation using

// ... subtraction and multiplication

// ... instead of calculating the remainder directly

remainder = (short) (dividend - division * 10);

// store the result in place for the next iteration

uBigBuf[uBigIndex] = (byte) division;

}

// the remainder is what we were after

// add '0' value to create ASCII digits

decBuf[decIndex] = (byte) (remainder + '0');

}

return decDigits;

}

/*

* pre-calculated array storing the number of decimal digits for big endian

* encoded number with len bytes: ceil(len * log_10(256))

*/

private static final byte[] BYTES_TO_DECIMAL_SIZE = { 0, 3, 5, 8, 10, 13,

15, 17, 20, 22, 25, 27, 29, 32, 34, 37, 39 };

要扩展输入大小,只需计算下一个十进制大小并将其存储在表中…

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值