Double Array and Char Array that Take up the Same Space

Discussion in 'Java' started by KevinSimonson, Oct 6, 2010.

  1. In C I can write a <union> and make it so the same space in memory can
    be treated both as a 64-bit <double> and a 4-element <short> array.
    Can I do that in Java too? In particular, can I have an array of
    fifty <double>s that take up 3200 bits of memory, and index into that
    array to get one particular <double>, and treat those same 3200 bits
    as an array of 200 <char>s, and index into that array to get one
    particular <char>? Any information on this would be greatly
    appreciated.

    Kevin S
     
    KevinSimonson, Oct 6, 2010
    #1
    1. Advertising

  2. KevinSimonson

    markspace Guest

    On 10/6/2010 10:23 AM, KevinSimonson wrote:

    > In C I can write a<union>
    > Can I do that in Java too?



    Pretty much no way. There's certainly no equivalent of C's unions in Java.

    However check out the NIO ByteBuffer. They allow you to make an array
    of bytes appear as other primitive types. However, this is not direct
    access like C, but involves software processing.
     
    markspace, Oct 6, 2010
    #2
    1. Advertising

  3. KevinSimonson

    Arne Vajhøj Guest

    On 06-10-2010 13:23, KevinSimonson wrote:
    > In C I can write a<union> and make it so the same space in memory can
    > be treated both as a 64-bit<double> and a 4-element<short> array.
    > Can I do that in Java too? In particular, can I have an array of
    > fifty<double>s that take up 3200 bits of memory, and index into that
    > array to get one particular<double>, and treat those same 3200 bits
    > as an array of 200<char>s, and index into that array to get one
    > particular<char>? Any information on this would be greatly
    > appreciated.


    I would try with a byte array with 400 elements, wrap it in
    a ByteArrayInputStream, wrap that in a DataInputStream, call mark
    at the beginning and then use skip and readXxx to read whatever
    data you need.

    Or if you are comfortable with NIO: try with a byte array with 400
    elements, use ByteBuffer.wrap and use getXxx(index) to read whatever
    data you need.

    Arne
     
    Arne Vajhøj, Oct 6, 2010
    #3
  4. KevinSimonson wrote:
    > In C I can write a <union> and make it so the same space in memory can
    > be treated both as a 64-bit <double> and a 4-element <short> array.
    > Can I do that in Java too? In particular, can I have an array of
    > fifty <double>s that take up 3200 bits of memory, and index into that
    > array to get one particular <double>, and treat those same 3200 bits
    > as an array of 200 <char>s, and index into that array to get one
    > particular <char>? Any information on this would be greatly
    > appreciated.


    If you can wrap the array into a class under your control, check out
    public static native long Double.doubleToLongBits(double);
    public static native long Double.doubleToRawLongBits(double);
    public static native double Double.longBitsToDouble(long);

    --

    "I'm a doctor, not a mechanic." Dr Leonard McCoy <>
    "I'm a mechanic, not a doctor." Volker Borchert <>
     
    Volker Borchert, Oct 6, 2010
    #4
  5. KevinSimonson

    Nigel Wade Guest

    On 06/10/10 18:23, KevinSimonson wrote:
    > In C I can write a <union> and make it so the same space in memory can
    > be treated both as a 64-bit <double> and a 4-element <short> array.
    > Can I do that in Java too? In particular, can I have an array of
    > fifty <double>s that take up 3200 bits of memory, and index into that
    > array to get one particular <double>, and treat those same 3200 bits
    > as an array of 200 <char>s, and index into that array to get one
    > particular <char>? Any information on this would be greatly
    > appreciated.
    >
    > Kevin S


    Sort of.

    You can't do it directly via pointers/arrays as you can in C. But if the
    block of memory is a byte[] array then you can wrap a
    java.nio.ByteBuffer around it. This allows you to read primitive data
    types from that Buffer.

    If the Buffer supports direct buffers then you should be able to get a
    ShortBuffer and a DoubleBuffer backed by the same region of memory. But
    you cannot guarantee that the different Buffers will share the same
    memory. If this is important then you would probably need to use a
    single ByteBuffer and read primitives from it using the position()
    method to set the correct location, then read using the relative get
    methods.

    This is a pretty unusual situation to be in. I can't think of many
    situations where you would need to treat the same memory region as short
    and double. There might be a better way in Java to achieve the same
    operation that you are attempting to duplicate from C.

    --
    Nigel Wade
     
    Nigel Wade, Oct 7, 2010
    #5
  6. KevinSimonson

    Roedy Green Guest

    On Wed, 6 Oct 2010 10:23:21 -0700 (PDT), KevinSimonson
    <> wrote, quoted or indirectly quoted someone who
    said :

    >In C I can write a <union>


    In Java there is nothing like union. Java is strictly write-once
    run-everywhere. Union behaves differently on big/little endian
    machines, among other problems.

    To pull off similar effects, you need logic similar to
    java.util.BitSet. Internally it is an array of longs. Externally it
    behaves like an array of booleans. It stores booleans as individual
    bits packed into 64-bit longs.

    Also have a look at how the nio package works inside.
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com

    You encapsulate not just to save typing, but more importantly, to make it easy and safe to change the code later, since you then need change the logic in only one place. Without it, you might fail to change the logic in all the places it occurs.
     
    Roedy Green, Oct 7, 2010
    #6
  7. KevinSimonson

    Nigel Wade Guest

    On 07/10/10 14:08, Thomas Pornin wrote:
    > According to KevinSimonson <>:
    >> In C I can write a <union> and make it so the same space in memory can
    >> be treated both as a 64-bit <double> and a 4-element <short> array.

    >
    > Actually it is not reliable in C either. Accessing the same space under
    > two distinct types implies a host of aliasing-related trouble,
    > especially when neither of the types is the ubiquitous "unsigned char".
    > Code which uses such tricks is prone to break when compiled with newer
    > compilers or with optimization flags. And, of course, it also has
    > portability issues, e.g. with endianness.
    >
    > The "safe" way is to keep the space under one type (e.g. an array of
    > eight "unsigned char") and access it through dedicated macros or inline
    > functions. This would need only two such functions, one for reading and
    > one for writing. Then, if I have a specific system on which the decoding
    > and encoding functions turn out to be a performance bottleneck (it
    > happens much less often than usually expected), then I could replace
    > them with a union-based trick, or inline assembly, or whatever does the
    > job. This way I have only two functions to modify (and not the thousands
    > of lines of code which use those functions), and the whole thing is much
    > more portable and reliable.
    >
    > In Java, you would do the same thing except for the last bit with inline
    > assembly, because that does not exist in Java (except if you resort to
    > JNI -- interface to native code -- but there is an overhead). This would
    > look like this (completely untested):
    >
    > class ArrayOfShortsOrDoubles {
    >
    > private short[] data;
    >
    > ArrayOfShortsOrDoubles(int len)
    > {
    > data = new short[len];
    > }
    >
    > int length()
    > {
    > return data.length;
    > }
    >
    > short get(int x)
    > {
    > return data[x];
    > }
    >
    > void set(int x, short value)
    > {
    > data[x] = value;
    > }
    >
    > double getDouble(int x)
    > {
    > int hi = (data[x] << 16) | (data[x + 1] & 0xFFFF);
    > int lo = (data[x+ 2] << 16) | (data[x + 3] & 0xFFFF);
    > return Double.longBitsToDouble(
    > ((long)hi << 32) | (lo & 0xFFFFFFFFL));
    > }
    >
    > void setDouble(int x, double value)
    > {
    > long v = Double.doubleToLongBits(value);
    > data[0] = (short)(v >>> 48);
    > data[1] = (short)(v >>> 32);
    > data[2] = (short)(v >>> 16);
    > data[3] = (short)v;
    > }
    > }
    >
    > Note that:
    >
    > -- I am considering here the case where you want an array of such
    > short-or-double values.
    > -- I am using big-endian conventions in the splitting of 64-bit
    > IEEE754 "double" values into four 16-bit "short".
    > -- I am indexing by 16-bit units, whether I want doubles or shorts.
    > -- Double.doubleToLongBits() normalizes NaN values; you may want to
    > use Double.doubleToRawLongBits() instead.
    >
    >
    > --Thomas Pornin


    The above is provided by java.nio.Buffer and its subclasses viz.
    ShortBuffer/DoubleBuffer. In addition, ByteBuffer also provides the
    ability to handle both big- and little-endian buffers.

    --
    Nigel Wade
     
    Nigel Wade, Oct 7, 2010
    #7
  8. KevinSimonson

    Stefan Ram Guest

    KevinSimonson <> writes:
    >In C I can write a <union> and make it so the same space in memory can
    >be treated both as a 64-bit <double> and a 4-element <short> array.
    >Can I do that in Java too? In particular, can I have an array of
    >fifty <double>s that take up 3200 bits of memory, and index into that
    >array to get one particular <double>, and treat those same 3200 bits
    >as an array of 200 <char>s, and index into that array to get one
    >particular <char>? Any information on this would be greatly
    >appreciated.


    You cannot do that in C.

    »When a value is stored in a member of an object of union type,
    the bytes of the object representation that do not
    correspond to that member but do correspond to other
    members take unspecified values«
    ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
    ISO/IEC 9899:1999 (E), 6.2.6.1#7
     
    Stefan Ram, Oct 8, 2010
    #8
  9. KevinSimonson

    Daniel Pitts Guest

    On 10/6/2010 10:23 AM, KevinSimonson wrote:
    > In C I can write a<union> and make it so the same space in memory can
    > be treated both as a 64-bit<double> and a 4-element<short> array.
    > Can I do that in Java too? In particular, can I have an array of
    > fifty<double>s that take up 3200 bits of memory, and index into that
    > array to get one particular<double>, and treat those same 3200 bits
    > as an array of 200<char>s, and index into that array to get one
    > particular<char>? Any information on this would be greatly
    > appreciated.
    >
    > Kevin S

    Java is not intended to be a systems level language. Even in C++, what
    you are asking for is undefined behavior. Instead, good design dictates
    that you maintain the type information for all bit patterns. Why is
    this something you are trying to do in Java?

    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
     
    Daniel Pitts, Oct 12, 2010
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Sydex
    Replies:
    12
    Views:
    6,568
    Victor Bazarov
    Feb 17, 2005
  2. Shuo Xiang

    Stack space, global space, heap space

    Shuo Xiang, Jul 9, 2003, in forum: C Programming
    Replies:
    10
    Views:
    2,939
    Bryan Bullard
    Jul 11, 2003
  3. Christian Seberino
    Replies:
    21
    Views:
    1,723
    Stephen Horne
    Oct 27, 2003
  4. Ian Bicking
    Replies:
    2
    Views:
    1,056
    Steve Lamb
    Oct 23, 2003
  5. lovecreatesbeauty
    Replies:
    1
    Views:
    1,102
    Ian Collins
    May 9, 2006
Loading...

Share This Page