Java 负 BigInteger toString

发布于 2024-11-17 14:46:31 字数 661 浏览 0 评论 0原文

我似乎对 Java 的 BigInteger 有一个二进制补码问题。 我有一个 64 位整数,其中只有 msb 和第二个 msb 设置为 1,其余为 0。

在十进制中,这达到:-4611686018427387904

我的应用程序的 Java 端接收这个十进制数作为字符串,并转换将其转换为 BigInteger,如下所示:

BigInteger bi = new BigInteger("-4611686018427387904", 10);

然后,它需要以二进制和十六进制形式显示该数字。 我尝试使用:

String bin = bi.toString(2);
String hex = bi.toString(16);

但我得到:

-100000000000000000000000000000000000000000000000000000000000000

-4000000000000000

而我期望得到:

1100000000000000000000000000000000000000000000000000000000000000

c000000000000000

有什么提示吗?

It seems I have a two's complement issue with Java's BigInteger.
I have a 64-bit integer where only the msb and the second msb are set to 1, the rest is 0.

In decimal this comes up to: -4611686018427387904

The Java side of my application receives this decimal number as a string, and converts it to BigInteger like so:

BigInteger bi = new BigInteger("-4611686018427387904", 10);

Then, it needs to display this number both in binary and hex forms.
I tried to use:

String bin = bi.toString(2);
String hex = bi.toString(16);

but I'm getting:

-100000000000000000000000000000000000000000000000000000000000000

-4000000000000000

whereas I expect to get:

1100000000000000000000000000000000000000000000000000000000000000

c000000000000000

Any tips?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

萌梦深 2024-11-24 14:46:31

数字始终适合 64 位:

如果您的数字始终适合 64 位,您可以将其放入 long 中,然后打印位/十六进制数字。

long l = bi.longValue();
String bin = Long.toBinaryString(l);
String hex = Long.toHexString(l);

System.out.println(bin);
System.out.println(hex);

数字可能并不总是适合 64 位:

如果数字总是适合 64 位,则您必须“手动”解决它。要将数字转换为其二进制补码表示形式,请执行以下操作:

  • 如果数字为正数,则不执行任何操作
  • 如果数字为负数:
    • 将其转换为其绝对值
    • 补充位
    • 添加 1

对于 BigInteger,转换如下所示:

if (bi.compareTo(BigInteger.ZERO) < 0)
    bi = bi.abs().not().add(BigInteger.ONE);

如果使用 bi.toString(2) 打印它,则仍然会得到符号字符,而不是前导 1。只需将 .replace('-', '1') 附加到字符串即可解决此问题。

Number always fits in 64 bits:

If your number always fits in 64 bits you can put it in a long and then print the bits / hex digits.

long l = bi.longValue();
String bin = Long.toBinaryString(l);
String hex = Long.toHexString(l);

System.out.println(bin);
System.out.println(hex);

Number may not always fit in 64 bits:

If the number does not always fit in 64 bits, you'll have to solve it "manually". To convert a number to it's two's complement representation you do the following:

  • If number is positive, do nothing
  • If number is negative:
    • Convert it to its absolute value
    • Complement the bits
    • Add 1

For a BigInteger the conversion looks as follows:

if (bi.compareTo(BigInteger.ZERO) < 0)
    bi = bi.abs().not().add(BigInteger.ONE);

If you print it using bi.toString(2) you'll still get the sign character, instead of a leading 1. This can be solved by simply appending .replace('-', '1') to the string.

も星光 2024-11-24 14:46:31

有一个 BigInteger.toByteArray() 方法,它将 BigInteger 的二进制补码表示形式返回为 byte[]。您所需要做的就是以十六进制或二进制形式打印该数组:

byte[] bs = bi.toByteArray();
for (byte b: bs) {
     System.out.print(String.format("%02X", 0xff & b));
}

There is a BigInteger.toByteArray() method, that returns two's complement representation of BigInteger as a byte[]. All you need is to print that array in hex or binary form:

byte[] bs = bi.toByteArray();
for (byte b: bs) {
     System.out.print(String.format("%02X", 0xff & b));
}
赠佳期 2024-11-24 14:46:31

二进制数1100000000000000000000000000000000000000000000000000000000000000绝对是一个正数,对吧。它等于 2^63 + 2^62。
我不明白为什么当您转换为基数 2 或基数 16 时,您会期望负数变为正数。

您将基数 n 表示与数字的内部表示混淆了。

The binary number 1100000000000000000000000000000000000000000000000000000000000000 is definitely a positive number, right. It's equal to 2^63 + 2^62.
I don't see why you'd expect a negative number to become positive when you convert to base 2 or base 16.

You are confusing the base n representation with the internal representation of numbers.

黎夕旧梦 2024-11-24 14:46:31

如果数字为 64 位或更少,那么解决此问题的简单方法是转换为 long,然后使用 Long.toHexString()

If the number is 64 bits or less, then the simple way to solve this is to convert to a long and then use Long.toHexString().

风吹短裙飘 2024-11-24 14:46:31

你是什​​么意思?
你想得到二进制补码吗?

如果你是这个意思,也许我可以给你一个例子

import java.util.*;
public class TestBina{
static void printBinaryInt(int i){
System.out.println("int:"+i+",binary:");
System.out.print("  ");
for(int j=31;j>=0;j--)
   if(((1<<j)&i)!=0)
    System.out.print("1");
   else
    System.out.print("0");
  System.out.println();
 }
 public static void main(String [] args){
  Random rand = new Random();
  int i = rand.nextInt();
  int j = rand.nextInt();
  printBinaryInt(i);
  printBinaryInt(j);
  printBinaryInt(10);
  printBinaryInt(-10);
 }
}  

what you mean?
Do you want to get Two's complement?

if you mean that, maybe i can give you an example

import java.util.*;
public class TestBina{
static void printBinaryInt(int i){
System.out.println("int:"+i+",binary:");
System.out.print("  ");
for(int j=31;j>=0;j--)
   if(((1<<j)&i)!=0)
    System.out.print("1");
   else
    System.out.print("0");
  System.out.println();
 }
 public static void main(String [] args){
  Random rand = new Random();
  int i = rand.nextInt();
  int j = rand.nextInt();
  printBinaryInt(i);
  printBinaryInt(j);
  printBinaryInt(10);
  printBinaryInt(-10);
 }
}  
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文