32 位有符号二进制字符串的 Java Integer.parseInt() 抛出 NumberFormatException

2024-01-04

这是Java Api的bug吗?

    int i = 0xD3951892;
    System.out.println(i); // -745203566
    String binString = Integer.toBinaryString(i);
    int radix = 2;
    int j = Integer.valueOf(binString, radix );
    Assertions.assertThat(j).isEqualTo(i);

我希望毫无疑问这是真的。但它抛出以下异常:

java.lang.NumberFormatException: For input string: "11010011100101010001100010010010"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:495)
at java.lang.Integer.valueOf(Integer.java:556)
at com.zhugw.temp.IntegerTest.test_valueof_binary_string(IntegerTest.java:14)

所以如果我有一个二进制 String ,例如11010011100101010001100010010010,Java中如何获取其十进制数(-745203566)? DIY?编写代码来实现下面的等式?


Integer.valueOf(String, int radix) and Integer.parseInt(String, int radix)只会解析值 -2 147 483 648 到 2 147 483 647 的数字,即 32 位有符号整数的值。

这些函数无法将二进制补码解释为二进制 (radix = 2),因为传递的字符串可以是任意长度,因此前导 1 可以是数字或符号位的一部分。我猜 Java 开发人员认为最合乎逻辑的处理方式是永远不接受二进制补码,而不是假设第 32 位是符​​号位。

他们将您的输入二进制字符串读取为无符号 3 549 763 730(大于最大 int 值)。要读取负值,您需要给出一个正二进制数-在前面签名。例如对于-5:

Integer.parseInt("1011", 2); // 11
    // Even if you extended the 1s to try and make two's complement of 5,
    // it would always read it as a positive binary value
Integer.parseInt("-101", 2); // -5, this is right

解决方案:

我建议,首先,如果您可以将其存储为正数,并自行添加额外的符号信息(例如-符号),这样做。例如:

String binString;
if(i < 0)
    binString = "-" + Integer.toBinaryString(-i);
else // positive i
    binString = Integer.toBinaryString(i);

如果您需要使用有符号的二进制字符串,为了以二进制补码形式(作为字符串)获取负数并将其解析为 int,我建议您手动获取补码,将其转换为 int,然后更正标志。回想一下,二进制补码 = 二进制补码 + 1,而二进制补码只是将每一位取反。

作为示例实现:

String binString = "11010011100101010001100010010010";
StringBuilder onesComplementBuilder = new StringBuilder();
for(char bit : binString.toCharArray()) {
    // if bit is '0', append a 1. if bit is '1', append a 0.
    onesComplementBuilder.append((bit == '0') ? 1 : 0);
}
String onesComplement = onesComplementBuilder.toString();
System.out.println(onesComplement); // should be the NOT of binString
int converted = Integer.valueOf(onesComplement, 2);
// two's complement = one's complement + 1. This is the positive value
// of our original binary string, so make it negative again.
int value = -(converted + 1);

您也可以编写自己的版本Integer.parseInt对于 32 位二进制补码。当然,这是假设您没有使用 Java 8 并且不能只使用Integer.parseUnsignedInt,@llogiq 在我打字时指出的。

编辑:你也可以使用Long.parseLong(String, 2)首先,然后计算二进制补码(并用 0xFFFFFFFF 屏蔽它),然后降级long向下int。写得更快,代码可能也更快。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

32 位有符号二进制字符串的 Java Integer.parseInt() 抛出 NumberFormatException 的相关文章

  • Java - 因内存不足错误而关闭

    关于如何最好地处理这个问题 我听到了非常矛盾的事情 并且陷入了以下困境 OOME 会导致一个线程崩溃 但不会导致整个应用程序崩溃 我需要关闭整个应用程序 但不能 因为线程没有剩余内存 我一直认为最佳实践是让它们离开 这样 JVM 就会死掉
  • 带有 Android 支持库 v7 的 Maven Android 插件

    我使用 maven android plugin 构建我的 android 应用程序 它依赖于 android 支持库 v4 和 v7 由于我没有找到如何从developer android com下载整个sdk 因此我无法使用maven
  • 使用 WebDriver 单击新打开的选项卡中的链接

    有人可以在这种情况下帮助我吗 场景是 有一个网页 我仅在新选项卡中打开所有指定的链接 现在我尝试单击新打开的选项卡中的任何一个链接 在下面尝试过 但它仅单击主 第一个选项卡中的一个链接 而不是在新选项卡中 new Actions drive
  • 如何在 Openfire 中使用 smack

    你好 我计划开发一个可以连接到 gtalk facebook 等的聊天客户端 我决定将 smack API 与 openfire 一起使用 但我需要很少的指导来了解如何将它与 openfire 服务器一起使用 openfire 是否提供了基
  • 如何强制jar使用(或jar运行的jvm)utf-8而不是系统的默认编码

    我的Windows默认编码是GBK 而我的Eclipse完全是utf 8编码 因此 在我的 Eclipse 中运行良好的应用程序崩溃了 因为导出为 jar 文件时这些单词变得不可读 我必须在 bat 文件中写入以下行才能运行该应用程序 st
  • tomcat 7.0.50 java websocket 实现给出 404 错误

    我正在尝试使用 Java Websocket API 1 0 JSR 356 中指定的带注释端点在 tomcat 7 0 50 上实现 websocket 以下是我如何对其进行编码的简要步骤 1 使用 ServerEndpoint注解编写w
  • Spring数据中的本机查询连接

    我有课 Entity public class User Id Long id String name ManyToMany List
  • 为什么Iterator接口没有add方法

    In IteratorSun 添加了remove 方法来删 除集合中最后访问的元素 为什么没有add方法来向集合中添加新元素 它可能对集合或迭代器产生什么样的副作用 好的 我们开始吧 设计常见问题解答中明确给出了答案 为什么不提供 Iter
  • 当 minifyEnabled 为 true 时 Android 应用程序崩溃

    我正在使用多模块应用程序 并且该应用程序崩溃时minifyEnabled true in the installed模块的build gradle 以下是从游戏控制台检索到的反混淆堆栈跟踪 FATAL EXCEPTION Controlle
  • Spring Data JPA:查询如何返回非实体对象或对象列表?

    我在我的项目中使用 Spring Data JPA 我正在演奏数百万张唱片 我有一个要求 我必须获取各种表的数据并构建一个对象 然后将其绘制在 UI 上 现在如何实现我的 Spring 数据存储库 我读到它可以通过命名本机查询来实现 如果指
  • 如何从日期中删除毫秒、秒、分钟和小时[重复]

    这个问题在这里已经有答案了 我遇到了一个问题 我想比较两个日期 然而 我只想比较年 月 日 这就是我能想到的 private Date trim Date date Calendar calendar Calendar getInstanc
  • 如何通过 Android 按钮单击运行单独的应用程序

    我尝试在 Android 应用程序中添加两个按钮 以从单独的两个应用程序订单系统和库存系统中选择一个应用程序 如图所示 我已将这两个应用程序实现为两个单独的 Android 项目 当我尝试运行此应用程序时 它会出现直到正确选择窗口 但是当按
  • Play.application() 的替代方案是什么

    我是 Play 框架的新手 我想读取conf文件夹中的一个文件 所以我用了Play application classloader getResources Data json nextElement getFile 但我知道 play P
  • 使用Java绘制维恩图

    我正在尝试根据给定的布尔方程绘制维恩图 例如 a AND b AND c我想在 Android 手机上执行此操作 因此我需要找到一种使用 Java 来执行此操作的方法 我找到了一个完美的小部件 它可以完成我在这方面寻找的一切布尔代数计算器
  • 无需登录即可直接从 Alfresco 访问文件/内容

    我的场景是这样的 我有一个使用 ALFRESCO CMS 来显示文件或图像的 Web 应用程序 我正在做的是在 Java servlet 中使用用户名和密码登录 alfresco 并且我可以获得该登录的票证 但我无法使用该票证直接从浏览器访
  • 如何让 Emma 或 Cobertura 与 Maven 一起报告其他模块中源代码的覆盖率?

    我有一个带有 Java 代码的多模块 Maven 设置 我的单元测试在其中一个模块中测试多个模块中的代码 当然 这些模块具有相互依赖性 并且在测试执行之前根据需要编译所有相关模块中的代码 那么 如何获得整个代码库覆盖率的报告 注意 我不是问
  • 禁用 Android 菜单组

    我尝试使用以下代码禁用菜单组 但它不起作用 菜单项仍然启用 你能告诉我出了什么问题吗 资源 菜单 menu xml menu menu
  • 替换文件中的字符串

    我正在寻找一种方法来替换文件中的字符串而不将整个文件读入内存 通常我会使用 Reader 和 Writer 即如下所示 public static void replace String oldstring String newstring
  • 使用 Java https 上传到 Imgur v3 错误

    我目前正在尝试使用他们当前的 API v3 上传到 imgur 但是我不断收到错误 错误 javax net ssl SSLException 证书中的主机名不匹配 api imgur com imgur com OR imgur com
  • 记录类名、方法名和行号的性能影响

    我正在我的 java 应用程序中实现日志记录 以便我可以调试应用程序投入生产后可能出现的潜在问题 考虑到在这种情况下 人们不会奢侈地使用 IDE 开发工具 以调试模式运行事物或单步执行完整代码 因此在每条消息中记录类名 方法名和行号将非常有

随机推荐