时髦的java按位操作?

时间:2016-05-30 02:46:58

标签: java bit-manipulation

我正在尝试使用大端表示法将大数字保存到文件中:

[0-255] * 256 ^ n

出于某种原因,当你移动一个long值时,java似乎使第0和第4个字节(第1和第5个......)相同

该简短代码段中的最后一列不应大于(256 - 1)= 255

我知道java没有无符号值,但是我想知道这段代码有什么问题,或者我在这里缺少什么

lbrtchx

import java.util.ArrayList;

public class BigEndian02Test{
    public static void main(String[] aArgs){
     int m8;
     long[] lBytL = new long[] { 1L, 256L, 65536L, 16777216L, 4294967296L, 1099511627776L, 281474976710656L, 72057594037927936L };
     long[] lBgEnd = new long[8];

     for(int i=0; (i < lBytL.length); ++i){
         for(long j =-1; (j < 2L); ++j){
             lVal = lBytL[i] + j;
             System.err.println("// __ lVal: |" + lVal + "|");
             for(int m=0; (m < 8); ++m){
                 m8 = m*8;
                 lBgEnd[m] = (long)((lVal & 0xFF) << m8);
                 System.err.println("// __ lBgEnd[" + m + "]: |" + lBgEnd[m] + "|" + (lBgEnd[m]/lBytL[m]) + "|");
             }// m
             System.err.println("~");
         }
    }
}

2 个答案:

答案 0 :(得分:1)

你的问题是你留下了一个表达式operator precedence而且你弄错了。

Shift <<>>>>>)的优先级高于按位AND &

所以:

lVal & 0xFF << m8

意思是:

lVal & (0xFF << m8)

你认为这意味着:

(lVal & 0xFF) << m8

添加括号,您的代码将更好用。

<强>更新

实际上,我认为你真的打算这样做:

(lVal >> m8) & 0xFF

当然,如果您只想将long数组转换为big-endian顺序的字节,请使用ByteBuffer

long[] lBytL = new long[] { 1L, 256L, 65536L, 16777216L, 4294967296L, 1099511627776L, 281474976710656L, 72057594037927936L };

ByteBuffer buf = ByteBuffer.allocate(lBytL.length * 8);
buf.order(ByteOrder.BIG_ENDIAN); // This is the default, so call not necessary, but here for clarity
for (long value : lBytL)
    buf.putLong(value);
byte[] bytes = buf.array();

以人类可读的格式打印结果:

for (int i = 0; i < bytes.length; i++) {
    System.out.printf("%02x ", bytes[i]);
    if (i % 8 == 7)
        System.out.println();
}

打印:

00 00 00 00 00 00 00 01 
00 00 00 00 00 00 01 00 
00 00 00 00 00 01 00 00 
00 00 00 00 01 00 00 00 
00 00 00 01 00 00 00 00 
00 00 01 00 00 00 00 00 
00 01 00 00 00 00 00 00 
01 00 00 00 00 00 00 00 

答案 1 :(得分:0)

谢谢你,安德烈亚斯。经过这么多的蠢事,我决定使用简单的算术表示算法。我想以一种不会给我带来惊喜的方式写作#34;当我将代码移植到ANSI C,C ++时,所以我选择了一个简单,直接的代码,kern看起来像:

val kStream = KafkaUtils.createDirectStream[String, String, StringDecoder, 
         StringDecoder](ssc, kParams, kTopic).map(_._2)
  println("Starting to read from kafka topic:" + topicStr)
kStream.foreachRDD { rdd =>

   if (rdd.toLocalIterator.nonEmpty) {

          val sqlContext = new org.apache.spark.sql.SQLContext(sc)
            sqlContext.read.json(rdd).registerTempTable("mytable")
            if (firstTime) {
                sqlContext.sql("SELECT * FROM mytable").printSchema()
            }
            val df = sqlContext.sql(selectStr)
            df.collect.foreach(println)
            df.rdd.saveAsTextFile(fileName)
            mergeFiles(fileName, firstTime)
            firstTime = false
           println(rdd.name)
        }