| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#1
| |||
| |||
| Hi, is there a way to determine the byte order of the underlying 'machine'? Portable? Regards, Rainer Joswig -- http://lispm.dyndns.org/ |
|
#2
| |||
| |||
| Rainer Joswig wrote: > Hi, > > is there a way to determine the byte order > of the underlying 'machine'? Portable? > > Regards, > > Rainer Joswig > PythonWin 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit (Intel)] on win32. Portions Copyright 1994-2006 Mark Hammond - see 'Help/About PythonWin' for further copyright information. >>> import sys >>> sys.byteorder 'little' >>> Just read the source and port it to Lisp ![]() |
|
#3
| |||
| |||
| Rainer Joswig <joswig@lisp.de> writes: > is there a way to determine the byte order > of the underlying 'machine'? Portable? Not in Common Lisp. Not in standard C either. In clisp, when you have clx: #+CLX-LITTLE-ENDIAN / #+CLX-BIG-ENDIAN In gcc on normal 32-bit platforms: #include <stdio.h> int main(void){ union { int i; char c[sizeof(int)]; } v; v.i=0x01020304; if((c[0]==0x01)&&(c[1]==0x02)(c[2]==0x03)(c[3]==0x04)){ printf("big endian\n"); }else if((c[3]==0x01)&&(c[2]==0x02)(c[1]==0x03)(c[0]==0x04)){ printf("little endian\n"); }else if((c[1]==0x01)&&(c[0]==0x02)(c[3]==0x03)(c[2]==0x04)){ printf("pdf endian\n"); /* IIRC */ }else{ printf("other endian\n"); } return(0); } You could do the same with some FFI in lisps having a FFI, or similar in lisp providing a low-level access to the memory. -- __Pascal Bourguignon__ http://www.informatimago.com/ Until real software engineering is developed, the next best practice is to develop with a dynamic system that has extreme late binding in all aspects. The first system to really do this in an important way is Lisp. -- Alan Kay |
|
#4
| |||
| |||
| Rainer Joswig <joswig@lisp.de> writes: > is there a way to determine the byte order > of the underlying 'machine'? Portable? You can obtain the answer to a related question by writing 1 to a file using an (UNSIGNED-BYTE 16) stream and then reading from the same file using an (UNSIGNED-BYTE 8) stream. Yes, behavior still depends on the implementation, so it only gives a partial answer. (In practice, it is highly probable that all implementations will work as we'd like them to.) A trivial first draft (run on x86): * (defun little-endian-p () (with-open-file (s "ub16" :direction utput :element-type '(unsigned-byte 16))(print (stream-element-type s) *trace-output*) ;implementation-dependent[*] (write-byte 1 s)) (with-open-file (s "ub16" :direction :input :element-type '(unsigned-byte 8)) (print (stream-element-type s) *trace-output*) ;implementation-dependent (= 1 (read-byte s)))) little-endian-p * (little-endian-p) (unsigned-byte 16) (unsigned-byte 8) t $ od -t x1 ub16 0000000 01 00 0000002 [*] See the last paragraph of the "Exceptional Situations" subsection of OPEN's specification. * * * I am tempted to think that the following is portable in C (it compiles cleanly with ``gcc -ansi -pedantic'', but that isn't everything, of course): ==> little-endian-p.c <== int main () { int i; i = 1; return (*(char *)&i == 0); } but I am also tempted to think that I might be missing some provision of the standard. Implementing a test that can also detect PDP-endianness is left as an exercise... ---Vassil. -- Bound variables, free programmers. |
|
#5
| |||
| |||
| In article <snwwsqlxl71.fsf@luna.vassil.nikolov.name>, Vassil Nikolov <vnikolov+usenet@pobox.com> wrote: > Rainer Joswig <joswig@lisp.de> writes: > > is there a way to determine the byte order > > of the underlying 'machine'? Portable? > > You can obtain the answer to a related question by writing 1 to a > file using an (UNSIGNED-BYTE 16) stream and then reading from the > same file using an (UNSIGNED-BYTE 8) stream. Yes, behavior still > depends on the implementation, so it only gives a partial answer. > (In practice, it is highly probable that all implementations will > work as we'd like them to.) Thanks for the answer! > A trivial first draft (run on x86): > > * (defun little-endian-p () > (with-open-file (s "ub16" :direction utput :element-type '(unsigned-byte 16))> (print (stream-element-type s) *trace-output*) ;implementation-dependent[*] > (write-byte 1 s)) > (with-open-file (s "ub16" :direction :input :element-type '(unsigned-byte 8)) > (print (stream-element-type s) *trace-output*) ;implementation-dependent > (= 1 (read-byte s)))) > > little-endian-p > * (little-endian-p) > > (unsigned-byte 16) > (unsigned-byte 8) > t That looked good. Then I ran it on a Lisp Machine: Command: (little-endian-p) (UNSIGNED-BYTE 16) Error: File was created with byte size 16; it may not be opened with byte size 8. For RJNXP:>joswig>ub16.lisp.1 LMFS:OPEN-LOCAL-LMFS-1 Arg 0: #P"RJNXP:>joswig>ub16.lisp.newest" Arg 1 (LMFS:LOGPATH): #P"RJNXP:>joswig>ub16.lisp.newest" Arg 2 (LMFS:ACCESS-PATH): #<FS:LOCAL-LMFS-ACCESS-PATH RJNXP using LOCAL-FILE 2050271547> Rest Arg (LMFS:OPTIONS): ( IRECTION :INPUT :ELEMENT-TYPE (UNSIGNED-BYTE 8) ...)s-A, <Resume>: Retry OPEN of RJNXP:>joswig>ub16.lisp.newest s-B: Retry OPEN using a different pathname s-C, <Abort>: Return to Lisp Top Level in a TELNET server s-D: Restart process TELNET terminal -> Sigh. It will be hardcoded, then. Btw., it is a little-endian machine, too. I tried another variant: use an ARRAY of 32 bits and another one of 4 times 8 bits displaced to it. Then compile the access code with SAFETY 0 to get rid of the runtime check. Does also not work on the platforms I'd be interested in... More embarrassing, the software I was looking at (not written by me, I swear), named it wrong - %big-endian was really %little-endian. > > $ od -t x1 ub16 > 0000000 01 00 > 0000002 > >[*] See the last paragraph of the "Exceptional Situations" > subsection of OPEN's specification. > > * * * > > I am tempted to think that the following is portable in C (it > compiles cleanly with ``gcc -ansi -pedantic'', but that isn't > everything, of course): > > ==> little-endian-p.c <== > > int main () { > int i; > i = 1; > return (*(char *)&i == 0); > } > > but I am also tempted to think that I might be missing some > provision of the standard. > > > Implementing a test that can also detect PDP-endianness is left as > an exercise... > > ---Vassil. -- http://lispm.dyndns.org/ |
|
#6
| |||
| |||
| Rainer Joswig <joswig@lisp.de> writes: > In article <snwwsqlxl71.fsf@luna.vassil.nikolov.name>, > Vassil Nikolov <vnikolov+usenet@pobox.com> wrote: > ... >> (In practice, it is highly probable that all implementations will >> work as we'd like them to.) > ... >> (defun little-endian-p () >> (with-open-file (s "ub16" :direction utput :element-type '(unsigned-byte 16))>> (print (stream-element-type s) *trace-output*) ;implementation-dependent[*] >> (write-byte 1 s)) >> (with-open-file (s "ub16" :direction :input :element-type '(unsigned-byte 8)) >> (print (stream-element-type s) *trace-output*) ;implementation-dependent >> (= 1 (read-byte s)))) >> ... > That looked good. Then I ran it on a Lisp Machine: > > Command: (little-endian-p) > (UNSIGNED-BYTE 16) > Error: File was created with byte size 16; it may not be opened with byte size 8. > For RJNXP:>joswig>ub16.lisp.1 Good point. I was in a unix state of mind. "Highly probable" it isn't. If there is no way to determine endianness programmatically[*] _within_ a Lisp Machine, perhaps it can be done extramurally, as it were, by writing to an (UNSIGNED-BYTE 16) value to a network destination and then getting an (UNSIGNED-BYTE 8) value echoed? (Ignoring how impractical this is for the sake of the exercise.) [*] At the Common Lisp level; I suppose there are low-level facilities that allow one to examine "raw" memory contents. By the way, perhaps it will help to know why exactly you need to detect endianness. A specific reason might hint at a specific solution. ---Vassil. -- Bound variables, free programmers. |
|
#7
| |||
| |||
| On 2008-01-08 01:47:38 +0000, Vassil Nikolov <vnikolov+usenet@pobox.com> said: > By the way, perhaps it will help to know why exactly you need to > detect endianness. A specific reason might hint at a specific > solution. Yes, this begs the question If it is nigh impossible todetermine endianness, what use could have this information apart from display purpose ("Your machine is little-endian")? The only case that springs to mind is interoprability at the file format level, where you'd have to write "by hand" 16, 32 or 64 bits values in the same way the _host_ does. But then that file format ought to be specified at the outset, and you would know which endianness to use regardless of the host's no? -- JFB |
|
#8
| |||
| |||
| On Jan 7, 6:09*pm, Pekka Niiranen <pekka.niira...@pp5.inet.fi> wrote: > *>>> import sys > *>>> sys.byteorder > 'little' > *>>> > > Just read the source and port it to Lisp ![]() You are plenty of right in that there are many libraries lacking for Lisp. Thanks for the reminding, though. |
|
#9
| |||
| |||
| > is there a way to determine the byte order > of the underlying 'machine'? Portable? > Easiest solution would be to compare the result of (machine-type) with the contents of a previously made assoc. list. Most probably a single pairings list could be constructed that would work in every implementation. |
|
#10
| |||
| |||
| In article <c9df440c-e46d-46a4-b623-bdcc10ae3e1f@m77g2000hsc.googlegroups.com>, kodifik@eurogaran.com wrote: > > is there a way to determine the byte order > > of the underlying 'machine'? Portable? > > > > Easiest solution would be to compare the result of > (machine-type) > with the contents of a previously made assoc. list. That would not be enough. On some processors two different operating systems (or even programs) may use different byte-orders. > > Most probably a single pairings list could be constructed that would > work in every implementation. -- http://lispm.dyndns.org/ |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.