You are not logged in.

#1 2013-03-09 02:30:56

BennyBolton
Member
From: Christchurch New Zealand
Registered: 2011-10-14
Posts: 63
Website

[Solved] Standard number library in c

In c is there a library to make standard integers (and vice versa) for storing in a file that may be used on different machines
It would also be nice to do this with floats as well, and to support variable widths

If anyone knows something that can point me in the right direction that would be very helpful

Last edited by BennyBolton (2013-03-09 09:58:12)


HP DV6 + Arch + Openbox

Offline

#2 2013-03-09 02:52:27

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

Re: [Solved] Standard number library in c

What do you mean by standard integers?  int is a basic data type, so is float.  stdio.h includes functions to read and write files.

What are you trying to do - I must be really misunderstanding this question as it seems to trivial.


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#3 2013-03-09 02:53:44

drcouzelis
Member
From: Connecticut, USA
Registered: 2009-11-09
Posts: 4,092
Website

Re: [Solved] Standard number library in c

I'm a little confused by your needs... How about write the integers as plain text, then read them back in like this:

scanf("%d", &num);

Offline

#4 2013-03-09 02:54:07

BennyBolton
Member
From: Christchurch New Zealand
Registered: 2011-10-14
Posts: 63
Website

Re: [Solved] Standard number library in c

I may have phrased it badly. I want some standard of interger and float that is independent of the current implementation, so that if I read/write it on another computer, it doesn't end up as some other number


HP DV6 + Arch + Openbox

Offline

#5 2013-03-09 02:55:45

BennyBolton
Member
From: Christchurch New Zealand
Registered: 2011-10-14
Posts: 63
Website

Re: [Solved] Standard number library in c

drcouzelis wrote:

I'm a little confused by your needs... How about write the integers as plain text, then read them back in like this:

scanf("%d", &num);

I would prefer them be in binary format


HP DV6 + Arch + Openbox

Offline

#6 2013-03-09 03:00:57

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

Re: [Solved] Standard number library in c

What do you mean independent of implementation?  Especially if you want it in binary (use read, instead of scanf), then it has to be coded in some way.  Is there some way you want the number coded into binary other than a straight writting of the bits to the file?  Binary is not dependent on implementation.

Last edited by Trilby (2013-03-09 03:02:49)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#7 2013-03-09 03:04:02

BennyBolton
Member
From: Christchurch New Zealand
Registered: 2011-10-14
Posts: 63
Website

Re: [Solved] Standard number library in c

Trilby wrote:

What do you mean independent of implementation?  Especially if you want it in binary (use read, instead of scanf), then it has to be coded in some way.  Is there some way you want the number coded into binary other than a straight writting of the bits to the file?

I want them written in binary, but a standard way, doesn't matter which way, so long as it can be read the same way on a different implementation (different endianness, architecture, etc)


HP DV6 + Arch + Openbox

Offline

#8 2013-03-09 03:20:56

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,441
Website

Re: [Solved] Standard number library in c

What is wrong with read and write from stdio.h?

Last edited by Trilby (2013-03-09 03:21:36)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#9 2013-03-09 03:24:55

BennyBolton
Member
From: Christchurch New Zealand
Registered: 2011-10-14
Posts: 63
Website

Re: [Solved] Standard number library in c

Trilby wrote:

What is wrong with read and write from stdio.h?

Depending on the system, the bytes in the numbers may be ordered differently. This is not standard in c


HP DV6 + Arch + Openbox

Offline

#10 2013-03-09 03:44:10

BennyBolton
Member
From: Christchurch New Zealand
Registered: 2011-10-14
Posts: 63
Website

Re: [Solved] Standard number library in c

I found http://techforb.blogspot.co.nz/2007/10/ … ndian.html which will help with integers, but still looking for floats


HP DV6 + Arch + Openbox

Offline

#11 2013-03-09 09:57:53

BennyBolton
Member
From: Christchurch New Zealand
Registered: 2011-10-14
Posts: 63
Website

Re: [Solved] Standard number library in c

Ok i've written my own library now
It doesn't give the number back, it writes it to a stream (why i wanted it)
Unsigned and signed ints work perfectly. Both big endian with signed being twos complement (haven't tested writting/loading as other but should work)
Floats are my own standard, i just load two signed ints (exponent and significand). Unfortunaly there is a loss a precision with this (test results below)

0.12345678901234567890  # this is the number i tested with
Double  0.12345678901234567737 8 bytes  # this is the number as double
Float   0.12345679104328155518 4 bytes  # this is the number as float
# I wrote then read the number for the sizes below (2-8 bytes)
Found   0.12304687500000000000 2 bytes at 0  # Expectedly crap precision
Found   0.12345504760742187500 3 bytes at 2  # Same
Found   0.12345677614212036133 4 bytes at 5  # Float size precision. The numbers are very similar
Found   0.12345677614212036133 5 bytes at 9  # same precision as 4 bytes (exponent increased to 2 bytes)
Found   0.12345678900601342320 6 bytes at 14
Found   0.12345678901215251244 7 bytes at 20
Found   0.12345678901234524716 8 bytes at 27 # same precision as double. The number is still pretty accurate but a couple significant figures of precision lost

Heres the code:

int bstream_getint(bstream *stream,bstream_int *num,int size){
	bstream_byte buf[BSTREAM_SIZE_MAX];
	int i,n;
	if(!stream || !num){
		return 0;
	}
	if(size<1){
		size=1;
	}
	if(size>BSTREAM_SIZE_MAX){
		size=BSTREAM_SIZE_MAX;
	}
	if(bstream_read(stream,buf,size,1)!=1){
		return 0;
	}
	n=0;
	if(buf[0]&128){
		n=1;
	}
	buf[0]&=127;
	num[0]=0;
	for(i=0;i<size;i++){
		num[0]<<=8;
		num[0]+=buf[i];
	}
	if(n){
		num[0]-=(((bstream_uint)1)<<((size<<3)-1));
	}
	return 1;
}

int bstream_putint(bstream *stream,bstream_int num,int size){
	bstream_byte buf[BSTREAM_SIZE_MAX];
	int i,n;
	if(!stream){
		return 0;
	}
	if(size<1){
		size=1;
	}
	if(size>BSTREAM_SIZE_MAX){
		size=BSTREAM_SIZE_MAX;
	}
	n=0;
	if(num<0){
		n=1;
		num+=(((bstream_uint)1)<<((size<<3)-1));
	}
	for(i=size-1;i>=0;i--){
		buf[i]=(num%256);
		num>>=8;
	}
	if(n){
		buf[0]|=128;
	} else {
		buf[0]&=127;
	}
	return bstream_write(stream,buf,size,1);
}

int bstream_getuint(bstream *stream,bstream_uint *num,int size){
	bstream_byte buf[BSTREAM_SIZE_MAX];
	int i;
	if(!stream || !num){
		return 0;
	}
	if(size<1){
		size=1;
	}
	if(size>BSTREAM_SIZE_MAX){
		size=BSTREAM_SIZE_MAX;
	}
	if(bstream_read(stream,buf,size,1)!=1){
		return 0;
	}
	num[0]=0;
	for(i=0;i<size;i++){
		num[0]<<=8;
		num[0]+=buf[i];
	}
	return 1;
}

int bstream_putuint(bstream *stream,bstream_uint num,int size){
	bstream_byte buf[BSTREAM_SIZE_MAX];
	int i;
	if(!stream){
		return 0;
	}
	if(size<1){
		size=1;
	}
	if(size>BSTREAM_SIZE_MAX){
		size=BSTREAM_SIZE_MAX;
	}
	for(i=size-1;i>=0;i--){
		buf[i]=(num%256);
		num>>=8;
	}
	return bstream_write(stream,buf,size,1);
}

int bstream_getfloat(bstream *stream,bstream_float *num,int size){
	int i,xb,expb;
	bstream_int x,exp;
	if(!stream || !num){
		return 0;
	}
	if(size<2){
		size=2;
	}
	if(size>BSTREAM_SIZE_MAX){
		size=BSTREAM_SIZE_MAX;
	}
	expb=size/5+1;
	xb=size-expb;
	if(!bstream_getint(stream,&exp,expb) || !bstream_getint(stream,&x,xb)){
		return 0;
	}
	xb<<=3;
	xb--;
	num[0]=ldexp(x/(double)(((bstream_uint)1)<<xb),exp);
	return 1;
}

static bstream_int _limitnum(bstream_int n,bstream_int size){
	size<<=3;
	size--;
	size=((bstream_int)1)<<size;
	if(n>=size-1){
		return size-1;
	}
	if(n<-size){
		return -size;
	}
	return n;
}

int bstream_putfloat(bstream *stream,bstream_float num,int size){
	int i,xb,expb;
	bstream_int x;
	int exp;
	if(!stream){
		return 0;
	}
	if(size<2){
		size=2;
	}
	if(size>BSTREAM_SIZE_MAX){
		size=BSTREAM_SIZE_MAX;
	}
	expb=size/5+1;
	xb=(size-expb)<<3;
	xb--;
	x=((double)(((bstream_uint)1)<<xb))*frexp(num,&exp);
	exp=_limitnum(exp,expb);
	x=_limitnum(x,size-expb);
	if(!bstream_putint(stream,exp,expb) || !bstream_putint(stream,x,size-expb)){
		return 0;
	}
	return 1;
}

FYI: bstream_int and bstream_uint are typedefs for long int signed and unsigned respectively, and bstream_float is a double
Edit: Also, BSTREAM_SIZE_MAX is 8, size in the function definition is size to read/write in bytes 1-8, floats can write 2-8
Edit2: Apparently my system is little endian, so i guess this works fine

Last edited by BennyBolton (2013-03-09 10:18:43)


HP DV6 + Arch + Openbox

Offline

#12 2013-03-09 10:20:13

jakobcreutzfeldt
Member
Registered: 2011-05-12
Posts: 1,041

Re: [Solved] Standard number library in c

FYI I think Glib has such standardized numerical types. It also has a million other things, though, so it might be more than what you need.

That said, this seems like one of those things that is reinvented in every large-scale C project.

Offline

#13 2013-03-09 10:25:32

BennyBolton
Member
From: Christchurch New Zealand
Registered: 2011-10-14
Posts: 63
Website

Re: [Solved] Standard number library in c

I looks like the glib numeric types just typedef c numeric types. there int8, int16, etc types don't mention endianess but i assume there typedefs of types in stdint.h, Might you  be mentioning extra functions in glib?

Last edited by BennyBolton (2013-03-09 10:27:46)


HP DV6 + Arch + Openbox

Offline

#14 2013-03-09 12:26:55

Cloudef
Member
Registered: 2010-10-12
Posts: 636

Re: [Solved] Standard number library in c

If you are only worried about endianess, you could just use ntohl/htonl, ntohs/htons.
You still need float unpacking for machines that don't support the network type (which you decide).

The stuff gets trickier, if the datatypes differ in size.
In these cases it's usually easiest to just serialize as string and read back.

Though, I think there was library that does all this already. I just don't remember the name right now.
EDIT:
It was this: http://hookatooka.com/poshlib/

EDIT2:
You also might want to look at: http://koti.kapsi.fi/jpa/nanopb/

Last edited by Cloudef (2013-03-09 12:37:21)

Offline

#15 2013-03-09 14:24:51

drcouzelis
Member
From: Connecticut, USA
Registered: 2009-11-09
Posts: 4,092
Website

Re: [Solved] Standard number library in c

BennyBolton wrote:

It doesn't give the number back, it writes it to a stream (why i wanted it)

Awww, you waited until the end to tell us what you actually wanted? sad

Offline

#16 2013-03-09 21:59:33

BennyBolton
Member
From: Christchurch New Zealand
Registered: 2011-10-14
Posts: 63
Website

Re: [Solved] Standard number library in c

Cloudef wrote:

If you are only worried about endianess, you could just use ntohl/htonl, ntohs/htons.
You still need float unpacking for machines that don't support the network type (which you decide).

The stuff gets trickier, if the datatypes differ in size.
In these cases it's usually easiest to just serialize as string and read back.

Though, I think there was library that does all this already. I just don't remember the name right now.
EDIT:
It was this: http://hookatooka.com/poshlib/

EDIT2:
You also might want to look at: http://koti.kapsi.fi/jpa/nanopb/

endianess is first thing i worry about but my code should also work with one's complement and sign/magnitude, but i haven't tested these. Also float storing splits the float into significand and exponent, multiplies/divides the significand to make an int (this is where precision is lost) and stores them as two signed integers. Its not the nicest way to do it but im happy for now. I cant see how this wouldn't work on systems with other float representations, but i'll still test it.


HP DV6 + Arch + Openbox

Offline

#17 2013-03-10 00:32:03

falconindy
Developer
From: New York, USA
Registered: 2009-10-22
Posts: 4,111
Website

Re: [Solved] Standard number library in c

There's <rpc/xdr.h> (man xdr) which is fairly widely used (part of libc) -- seems like it might be what you want.

Offline

Board footer

Powered by FluxBB