• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

convert long to byte array and back

 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I want to store a long in a byte array, transfer it over a network, then convert it back to a long. I do this:

and then back:

But this only works for integers, even though I use longs or cast to longs. How is this possible? How do I get my long back?
 
Ranch Hand
Posts: 518
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
In Java, a long is 8 bytes not 4.
 
Ranch Hand
Posts: 1078
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Why reinvent the wheel? The wrapper classes such as java.lang.Long provide a byteValue() method to get it as a byte and the java.lang.Byte wrapper provides longValue(), intValue(), etc. methods to convert back. I've never had reason to use these so I apologize if it's a stupid suggestion.
 
Ranch Hand
Posts: 381
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Ken Blair:
Why reinvent the wheel? The wrapper classes such as java.lang.Long provide a byteValue() method to get it as a byte and the java.lang.Byte wrapper provides longValue(), intValue(), etc. methods to convert back. I've never had reason to use these so I apologize if it's a stupid suggestion.



Those methods are of some use but not for this. From the API byteValue of Long

"the numeric value represented by this object after conversion to type byte."

The keyword there being conversion. So you are turning an 8 byte number into 1 byte number and as such losing 7 bytes worth of data.

As the previous poster mentioned longs are 8 bytes not 4. A useful class to look at is java.io.DataInputStream which has methods for creating primitives from bytes.

For example for readLong


Which as you can see uses readInt which in turns reads each byte and does it's think with them.

Anyway the DataInputStream and DataOutputStream classes give you full working source for all the primitive conversions. But in fact you don't have to do it on your own at all.

If you want to store primitives as bytes like that do this...



and basically everything flipped to read it back in....

 
Ranch Hand
Posts: 1608
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Use the java.nio buffers for this kind of data conversion.
 
Maximilian Xavier Stocker
Ranch Hand
Posts: 381
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Tony Morris:
Use the java.nio buffers for this kind of data conversion.



Why would that be better than using java.io.DataInputStream for this purpose?
 
Ken Blair
Ranch Hand
Posts: 1078
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I actually wondered how it could convert a long which is greater than one byte to a single byte, but I guess I assumed the lack of a toByteArray() or equivalent meant that it must be able to convert them somehow.
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
[Maximilian]: Why would that be better than using java.io.DataInputStream for this purpose?

Generally using NIO can lead to significantly better performance. Though in some cases there's no difference - and occasionally the performance is worse. More to the point though, most people seem to find the NIO classes harder to understand than the IO classes. Especially for people new to NIO, or to IO for that matter. If Reinout is currently using IO classes, the simplest solution will probably be to use a DataOutputStream, sticking with IO classes. But if the performance needs improvement, it may be helpful to replace most (or all) of the IO classes with NIO classes.
 
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I took a long look at many questions like this, and found this post... I didn't like the fact that the conversion code is duplicated for each type, so I've made a generic method to perform the task:



See full post
 
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Adam Zehavi wrote:...so I've made a generic method to perform the task:...


Any reason why you've revived a 7-year old thread to tell us this?

Winston
 
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Adam Zehavi wrote:I took a long look at many questions like this, and found this post... I didn't like the fact that the conversion code is duplicated for each type, so I've made a generic method to perform the task:



See full post




As already mentioned (in this 7 year old topic), what would be the purpose of reinventing the wheel? Why can't you just use a ByteBuffer?



Henry
 
Adam Zehavi
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
7 or 15 does not matter it can always be of some service, I've looked this up because I needed it, and I got closer to the answer on this page.

Plus, in my case I needed to have this conversion on both Java and Embedded C, so that is why
 
Marshal
Posts: 79177
377
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Welcome to the Ranch

That method almost certainly contains a serious error in the bit about n-1*8, I am afraid.
 
Adam Zehavi
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

That method almost certainly contains a serious error in the bit about n-1*8, I am afraid.



Ha Ha.... I missed that one...
 
Master Rancher
Posts: 4806
72
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
A "generic method" means something different in Java. But it looks like you're trying to make a method that takes an undocumented parameter "n" that means... ummm... maybe the number of bytes? Which presumably will not ever be greater than 8? Ok, I suppose that could be used to reduce code duplication compared to the code from the page you cited (whose methods look extremely similar to what's in DataInputStream and DataOutputStream, of course). But if you're reducing duplication, why not put it in a loop? Don't you need a loop anyway so that your result has only n bytes? Why not show actual working code here?

I would guess, however, that the evil duplicated code you're replacing is actually faster, and that's probably why DataInputStream and DataOutputStream were written as they were. Duplication isn't always evil, especially if it's compact and easy to understand, and it's encapsulated in a library where most people will never need to look at it; they just use it.
 
Adam Zehavi
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I was trying to keep the answer in the spirit of the question, and what I was looking for, all together, that is why I didn't add the loop.
As for performance, I take performance very seriously when it comes to large numbers of iterations, over a short period of time, then I would most defiantly use a faster method, but in my case/s I need a once in every 1-4 seconds to perform that conversion, so it doesn't really matter... in any case the final method looks like this, I know this is not very efficient, right now I'm more into generic(write once utilize for many NOT real Java Generic types):

 
Mike Simmons
Master Rancher
Posts: 4806
72
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Cool, thanks for clarifying.

One thing about library code is that, although it's usually a bad idea to optimize prematurely, the fact that many different people may use a method can mean that someone, somewhere actually does use that method in a tight loop repeated many times, and actually does benefit from it being faster. So widely-used library code has more reason to be optimized than code that only a few people use.
 
Adam Zehavi
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Agreed... Will add some docs to mention these facts!
 
Winston Gutkowski
Bartender
Posts: 10780
71
Hibernate Eclipse IDE Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Adam Zehavi wrote:I take performance very seriously...


Then you might be interested to know that
Class<? extends Number> dataType = data.getClass();
if (dataType == Byte.class) {...

takes about 8 times as long as
if (dataType instanceof Byte) {...
(at least on my computer)...and the latter handles nulls.

Sometimes the simplest is the best.

Winston
 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Aren’t the wrapper classes all final? The instanceof operator is much more reliable with final classes.
But don’t the Wrapper classes all have a static SIZE field which records the number of bits used? You can use that with << 3 to convert the bits to bytes. That may hit problems with BigDecimal and BigInteger which extend Number but don’t have the SIZE field.
 
Adam Zehavi
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Winston Gutkowski wrote:

Adam Zehavi wrote:I take performance very seriously...


Then you might be interested to know that
Class<? extends Number> dataType = data.getClass();
if (dataType == Byte.class) {...

takes about 8 times as long as
if (dataType instanceof Byte) {...
(at least on my computer)...and the latter handles nulls.



WOW... I'm new here and already liking it...
To be honest I've never checked this one out, I've been told at the beginning of my carrier that the opposite is true and I've taken it like a fool.

After simulating on my computer I've came with the following results:

equals 1000000 iterations duration: 78, 51, 59, 45, 47, 47 ms
instanceof 1000000 iterations duration: 43, 39, 51, 42, 43, 45 ms

I've called on the method I've posted earlier, once with '==' and once with instanceof.

Thanks for the input...
 
Adam Zehavi
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Campbell Ritchie wrote:
But don’t the Wrapper classes all have a static SIZE field which records the number of bits used? You can use that with << 3 to convert the bits to bytes.

That may hit problems with BigDecimal and BigInteger which extend Number but don’t have the SIZE field.



I don't follow?
 
Mike Simmons
Master Rancher
Posts: 4806
72
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm confused too. Looks like Adam is already using the SIZE field, and whether he uses (Long.SIZE / Byte.SIZE) or (Long.SIZE >> 3) doesn't make much difference; it's a compile-time constant anyway. I would argue the former is more readable. The SIZE field would be more useful if we could make use of it without knowing what particular class the data is an instance of - but I don't see how to do that without reflection, e.g.

That might minimize code reuse, but is probably even slower - and as Campbell notes, will have problems if Data is a BigInteger or BigDecimal, or AtomicInteger or AtomicLong or other subclass without a SIZE.
 
Adam Zehavi
Greenhorn
Posts: 11
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Some results:

equals 1000000 iterations duration: 284
equals <<3 1000000 iterations duration: 243
instanceof 1000000 iterations duration: 248

instanceof <<3 1000000 iterations duration: 206

And it keeps coming this way... where the bold ones race...
 
Campbell Ritchie
Marshal
Posts: 79177
377
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Simmons wrote:I'm confused too. Looks like Adam is already using the SIZE . . .

Yes, I missed that. Sorry
 
rubbery bacon. rubbery tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic