在字节数组中表示一个数字(java编程)

     2023-02-23     275

关键词:

【中文标题】在字节数组中表示一个数字(java编程)【英文标题】:Representing a number in a byte array (java programming) 【发布时间】:2011-02-21 13:42:01 【问题描述】:

我试图在一个两字节数组中表示端口号 9876(或十六进制的 0x2694):

class foo 
     public static void main (String args[]) 
   byte[] sendData = new byte[1];

   sendData[0] = 0x26;
   sendData[1] = 0x94;
     

但是我收到了一个关于可能会丢失精度的警告:

foo.java:5: possible loss of precision
found   : int
required: byte
   sendData[1] = 0x94;
                 ^
1 error

如何在两字节数组中表示数字 9876 而不会丢失精度?

注意:我选择了@Björn 的代码作为正确答案,但@glowcoder 的代码也很好用。这只是解决同一问题的不同方法。谢谢大家!

【问题讨论】:

请注意,通过网络发送的扁平化数据结构通常使用 Java 中的 DataOutputStream(或其子类 ObjectOutputStream)来完成。无需每次都重新发明bitfiddling :-) @meriton: 更好的是,使用java.nio.ByteBuffer 可以做到这一切,不必处理 IOException,也可以控制字节序。 【参考方案1】:

您是否尝试过转换为字节?例如

sendData[1] = (byte)0x94;

【讨论】:

那会导致我的精度下降,不是吗? @Mark:它会让编译器清楚你正在做你想做的事。 0x94 在一个字节的范围内,所以这里没有实际的精度损失。 我以为一个字节的范围是-128到127,0x94是148 @Mark - 0x94 作为一个字节实际上不是 148,而是 -108。 @Mark:嗯……不。看位,一个字节的范围是0b00000000到0b11111111,0x94=0b10010100,正好在它的范围内。按位,“有符号字节”的概念没有任何意义。只有当您将八位序列解释为整数时,它才开始变得清晰。【参考方案2】:

0x94 是十进制的 148,超出了 java 中字节的范围(-128 到 127)。 您可以执行以下操作之一:

1) 强制转换可以正常工作,因为它将保留二进制表示(对于 0x00 到 0xFF,没有有意义的位被截断):

 sendData[1] = (byte)0x94; 

2) 0x94 作为有符号字节的二进制表示是-108(-0x6C),所以下面的效果是一样的:

sendData[1] = -0x6C; //or -108 in decimal

【讨论】:

要将有符号字节转换回其无符号整数形式,您可以简单地写b & 0xff【参考方案3】:

Björn 对使用流给出了一个很好的通用答案。你也可以使用java.nio.ByteBuffer 来做同样的事情,这会导致代码稍微少一些,并且你还可以控制输出的字节序(字节顺序)。

创建字节数组:

public static byte[] toByteArray(int bits) 
    ByteBuffer buf = ByteBuffer.allocate(4);
    buf.putInt(bits);
    return buf.array();

反转它:

public static int fromByteArray(byte[] b) 
    ByteBuffer buf = ByteBuffer.wrap(b);
    return buf.getInt();

【讨论】:

【参考方案4】:

我的第一个答案是位移,但再想一想,我认为使用输出流可能会更好,更容易理解。我通常避免强制转换,但如果您不寻求通用解决方案,我想这没关系。 :)

使用流,一个通用的解决方案:

public byte[] intToByteArray(final int i) throws java.io.IOException 
    java.io.ByteArrayOutputStream b = new java.io.ByteArrayOutputStream();
    java.io.DataOutputStream d = new java.io.DataOutputStream(b);
    d.writeInt(i);
    d.flush();

    return b.toByteArray();

然后反转它:

public int byteArrayToInt(final byte[] b) throws IOException 
    java.io.ByteArrayInputStream ba = new java.io.ByteArrayInputStream(b);
    java.io.DataInputStream d = new java.io.DataInputStream(ba);

    return d.readInt();

【讨论】:

您也可以使用 java.nio.ByteBuffer 进行一般性操作,并在必要时控制字节序。我已经为这种可能性添加了答案。【参考方案5】:

您必须转换为 (byte),因为 java 中的默认数字类型是 int,它大于 byte。只要值适合字节,就可以转换。

【讨论】:

【参考方案6】:

试试这个:

sendData[0] =(byte)0x26
sendData[1] =(byte)0x94

或者这个:

sendData[0] =(byte)38
sendData[1] =(byte)148

您必须将数据转换为字节才能将其分配给字节!

这并不意味着你失去了精度,只是写 0x26 意味着一个 int 到 Java 编译器..

但还要注意:一个字节的范围是从 -128 到 127,所以在 0x94=148 的情况下,它会在字节转换后表示为 '-108' ,所以它在数学计算中不能正常工作..

【讨论】:

【参考方案7】:

这是因为 Java 中的所有内容都已签名。 0x94 (148) 大于 Byte.MAX_VALUE(2^7-1)。

你需要的是

public static byte[] intToByteArray(int value) 
    byte[] b = new byte[4];
    for (int i = 0; i < 4; i++) 
        int offset = (b.length - 1 - i) * 8;
        b[i] = (byte) ((value >>> offset) & 0xFF);
    
    return b;

【讨论】:

注意,这会完成 int 的所有 4 个字节......你只需要其中的两个。剩下的就很简单了。 这有两个错误——这不是因为所有内容都已签名,而是因为 0x94 是一个 int,而不是一个字节,其次是 char 类型是无符号的,第三——该代码是一个笑话吗?如果你只是在和那个人打交道,那可能值得 +1 :) 如果你用 (byte) 沮丧的话,原来的很好 0x94 是一个 int,因为它不适合字节 because bytes are signed。你是正确的,字符是无符号的 - 但是,这是规则的例外,因为它不是 intended 是一个数字 - JavaGods 决定他们的所有数字都将被签名。你能像数字一样使用它来优化字符串吗?是的你可以。它是否打算用作数字?否。Character 类是否扩展了 Number 类?不。第三,不,这段代码不是开玩笑,这是将任何 int 转换为字节数组以准确表示其位的合法方式。过去我用它来创建 TCP/IP 数据包。 我试过你的代码,效果很好。感谢您帮助初学者学习 Java!

如何在java中表示一个空列表? [复制]

...问题描述】:我有这个类的构造函数以一个字符串和一个数组列表作为参数;classFooStringide;ArrayListlist;publicTypeOperator(Stringide,ArrayListlist)this.ide=ide; 查看详情

零长度数组如何在内存中表示?

】零长度数组如何在内存中表示?【英文标题】:Howisthezerolengtharrayrepresentedinmemory?【发布时间】:2015-07-1921:43:28【问题描述】:Java原语对象被映射到本机原语。所以我的问题是charvalue[]=newchar[0];是如何表示的?它是否取决于(... 查看详情

如何在 TypeScript 中表示包含多种类型的二维数组?

】如何在TypeScript中表示包含多种类型的二维数组?【英文标题】:HowdoIrepresentatwo-dimensionalarraycontainingmultipletypesinTypeScript?【发布时间】:2019-12-3103:52:33【问题描述】:我正在学习TypeScript。我在学习的时候有一个问题constarr=[[\'192... 查看详情

java示例代码_在一个值中表示4种布尔可能性

java示例代码_在一个值中表示4种布尔可能性 查看详情

如何在 Rust 中表示指向 C 数组的指针?

】如何在Rust中表示指向C数组的指针?【英文标题】:HowtorepresentapointertoaCarrayinRust?【发布时间】:2017-01-0515:17:26【问题描述】:我需要Rust中的extern"C"FFI函数,并希望接受一个固定大小的数组。C代码传递如下内容://Ccodee... 查看详情

如何在 ember-data 模型中表示数组?

】如何在ember-data模型中表示数组?【英文标题】:Howtorepresentarrayswithinember-datamodels?【发布时间】:2012-08-2312:15:15【问题描述】:当模型包含数组时,是否有必要使用DS.hasMany指向DS.Model?即使数组元素不是真正的模型(没有自己... 查看详情

在java中表示树层次结构[重复]

】在java中表示树层次结构[重复]【英文标题】:Representtreehierarchyinjava[duplicate]【发布时间】:2012-06-2617:18:17【问题描述】:可能重复:Javatreedata-structure?我想在java中表示一个层次结构。层次结构可以是以下形式Key||-Value1||-Value11||... 查看详情

MFC:在编辑框中表示邻接矩阵

】MFC:在编辑框中表示邻接矩阵【英文标题】:MFC:Representingadjacencymatrixineditbox【发布时间】:2019-12-1315:07:17【问题描述】:我有一个基于对话框的程序(MFC),我想在其中进行邻接图表示。我有一个编辑框(IDC_EDIT)和MFCMaskedEdit控件(... 查看详情

batbat中特殊符号

...Windows批处理中特殊符号的作用:@隐藏命令的回显。~在for中表示使用增强的变量扩展;在set中表示使用扩展环境变量指定位置的字符串;在set/a中表示按位取反。%使用两个%包含一个字符串表示引用环境变量。比如一个%time%可以... 查看详情

如何在 Python 中表示无限数?

】如何在Python中表示无限数?【英文标题】:HowcanIrepresentaninfinitenumberinPython?【发布时间】:2011-12-0812:53:54【问题描述】:如何在python中表示无限数?无论您在程序中输入哪个数字,任何数字都不应大于这个无穷大的表示。【问... 查看详情

如何在 JavaScript 中表示浮点数? [复制]

】如何在JavaScript中表示浮点数?[复制]【英文标题】:HowcanirepresentafloatinJavaScript?[duplicate]【发布时间】:2021-10-1520:34:45【问题描述】:我是JavaScript的新手。在python中,我可以创建一个条件来检查数字是否是这样的浮点数:num=1.5... 查看详情

在定义中表示 UNO 输出参数

...型的参数调用,所以自动化桥enablesaworkaround——传入一个数组;索引0处的元素被修改,可以在函数外 查看详情

如何在 Scala 中表示一个空字符?

】如何在Scala中表示一个空字符?【英文标题】:HowdoIrepresentanemptyCharinScala?【发布时间】:2012-01-0812:21:54【问题描述】:valmychar=\'\'不编译并导致以下错误:错误:未闭合的字符文字valmychar=\'a\'等都很好。我尝试过将“”转换为... 查看详情

如果它们来自数据源,如何在 graphql 模式中表示枚举?

...个RESTapi。其中一个路径是/types/,它只返回一个json字符串数组,每个字符串都是一个类型的名称。此类型在架构中的其他地方用作其他对象的类型枚举值。我如何在gr 查看详情

在 C++ 中表示二维数组的最佳方法,其大小在运行时确定

】在C++中表示二维数组的最佳方法,其大小在运行时确定【英文标题】:Bestwaytorepresenta2-DarrayinC++withsizedeterminedatruntime【发布时间】:2010-09-2008:32:03【问题描述】:在C++中,我想做类似的事情:intn=get_int_from_user();char*matrix=newchar[n... 查看详情

如何在java中的内存中表示null[duplicate](代码片段)

...isnullinJavamemory有没有人知道如何在对象或任何东西的内存中表示空值。在点网中,它由空指示符布尔值和相应类型的值(Referhere)表示。那么有谁知道它是如何在java中完成的?答案来自JVMspecification,section2.4:Java虚拟机规范没有... 查看详情

你如何在 Haskell 中表示一个图形?

】你如何在Haskell中表示一个图形?【英文标题】:HowdoyourepresentagraphinHaskell?【发布时间】:2012-04-0116:33:56【问题描述】:使用代数数据类型在haskell中表示树或列表很容易。但是您将如何以印刷方式表示图形?看来你需要有指针... 查看详情

在 Java 中表示和比较地理位置

】在Java中表示和比较地理位置【英文标题】:RepresentingandcomparinggeographiclocationsinJava【发布时间】:2015-04-2510:03:04【问题描述】:我试图弄清楚如何表示地理位置,但我似乎无法在SE文档中找到任何相关的类。我想做这样的事情... 查看详情