Message Boards Message Boards

0
|
5135 Views
|
5 Replies
|
0 Total Likes
View groups...
Share
Share this post:

How Do I Get the File Write Size of A Specific Mathematica Data Type?

Posted 10 years ago

Hello,

I would like to use StreamPos[] to seek through a binary file in "Real32" sized chunks. I can calculate the offset of the data in the stream and move by "Character8" positions.

How do I get the file size of a "Real32" or any other non byte numeric? In the 'C' programming language there is a sizeof() macro for this purpose.

Is there an equivalent function for getting SizeOf["Real32"] or SizeOf["Real64"] ?

I had thought of a method using a temorary file to get system sizes of written values. (ie: write a single value to a temp file and get the size of the file) This seems like a lot of effort , and overhead, for something that must surely already exist in the language.

Thanks.

POSTED BY: Peter Willis
5 Replies

The size is already incorporated in the name... "Real32" -> 4 bytes, "Real64" -> 8 bytes, "Integer24" -> 3 bytes etc.

POSTED BY: Ilian Gachevski
Posted 10 years ago

I think you're misunderstanding what I mean. I want a function that returns the integer number value of the byte size of a numerical data type.

Here is the work around that I have devised.

GetTypeSize[datatype_] :=
(
Module[
(*incoming parameters*)
{atype=datatype},
Block[{fp},
fp = OpenWrite["a1234pacximus.bin",BinaryFormat->True];
a = BinaryWrite[fp,1,atype,ByteOrdering->-1];
Close[fp];
];(*end block*)
FileByteCount["a1234pacximus.bin"]
](*end of module*)
)
(*end if GetTypeSize*)

Examples of calling this function would be:

realsz = GetTypeSize["Real32"];
intsz = GetTypeSize["Integer24"];

I thought the language designers may have a function for getting the size of a type already.

POSTED BY: Peter Willis

Given the small number of binary types available, and the fact that the name of each type spells out its size, defining such a function is trivial.

In[2]:= sizeMap = <|"Character8" -> 1, "Character16" -> 2, 
   "Integer8" -> 1, "Integer16" -> 2, "Integer24" -> 3, 
   "Integer32" -> 4, "Integer64" -> 8, "Integer128" -> 16, 
   "UnsignedInteger8" -> 1, "UnsignedInteger16" -> 2, 
   "UnsignedInteger24" -> 3, "UnsignedInteger32" -> 4, 
   "UnsignedInteger64" -> 8, "UnsignedInteger128" -> 16, 
   "Real32" -> 4, "Real64" -> 8, "Real128" -> 16, "Complex64" -> 8, 
   "Complex128" -> 16, "Complex256" -> 32|>;

In[3]:= sizeMap["Real32"]

Out[3]= 4
POSTED BY: Ilian Gachevski
Posted 10 years ago

The problem with your constant code is that you have now created a scope issue and it's not extensible. This means that if one used it hidden in a package, and additional types are added to the system, the package would fail with the new types until teh package was reprogrammed.

I'm not sure the issue is as trivial as you expect.

An additional fix for my original code uses a non-file stream. That would eliminate the need to open a file. A memory stream should work just as well.

POSTED BY: Peter Willis

I can see some advantage in your write-and-find-out approach in case a new and mysterious binary type appears out of somewhere. But you asked why that's not a built-in function, and these types are not user-extensible in Mathematica. An internal function would also need to be extended if new formats are added to the system, just as the implementation of BinaryRead/Write would need to be extended.

The size for any of the existing binary input/output types is not hidden from you in any way, and I find it unlikely any new hypothetical additions would start obscuring it.

How does sizeof() get implemented in a C compiler, at the lowest level? Well, probably someone reads the architecture-specific ABI documentation, finds an appropriate table of fundamental data type sizes and alignments, and hardcodes these in...

POSTED BY: Ilian Gachevski
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract