-
-
Save meijeru/952998 to your computer and use it in GitHub Desktop.
Red/System [ | |
Title: "Form" | |
Purpose: {formats an integer in a c-string, as signed decimal or as hex} | |
Author: "Rudolf W. MEIJER" | |
File: %form-number.reds | |
Version: 0.7 | |
Date: 27-May-2011 | |
Notes: {Improved version, not final} | |
] | |
#include %stringf.reds | |
form-signed: func [ | |
i [integer!] | |
return: [c-string!] | |
/local s [c-string!] r [c-string!] c [integer!] n [logic!] | |
][ | |
if zero? i [return "0"] | |
s: make-string 11 | |
n: negative? i | |
if n [i: negate i] | |
c: 11 | |
while [i <> 0][ | |
s/c: #"0" + (i // 10) | |
i: i / 10 | |
c: c - 1 | |
] | |
if n [s/c: #"-" c: c - 1] | |
r: copy-part s + c 11 - c | |
free s | |
r | |
] | |
form-hex: func [ | |
i [integer!] | |
return: [c-string!] | |
/local s [c-string!] r [c-string!] c [integer!] d [integer!] | |
][ | |
if zero? i [return "0"] | |
s: make-string 8 | |
c: 8 | |
while [i <> 0][ | |
d: i // 16 | |
if d > 9 [d: d + 7] ; 7 = (#"A" - 1) - #"9" | |
s/c: #"0" + d | |
i: i / 16 | |
c: c - 1 | |
] | |
r: copy-part s + c 8 - c | |
free s | |
r | |
] |
Thanks. Meanwhile I have defined a function abs which does the negation, and I have realised that the substring manipulation is not necessary at all. One can already just add an integer to a c-string! value which is in fact a pointer. See my new version.
More simplfication in the calculation of the bytes for the individual digits. See latest version.
Good to know that c-string! arithmetic is already working. I will need to review the internal code paths and generated code to be sure it is working correctly.
The newest version provides both decimal (signed) and hexadecimal (unsigned) formats. It uses memory allocation (calloc) and freeing (free) as provided in my other gist: stringf.reds which was insppired by Kaj de Vos' C-library. Please note that free can only free a block of memory previously allocated by malloc/calloc.
Function 'form-hex will be surely useful to print memory addresses for debugging purpose.
I suspect form-signed may give an incorrect result when printing -2147483648 as the number currently cannot be properly negated.
Peter is right, form-signed -2147483648
gives -./,),(-*,(
as result.
Rudolf, I did a quick patch in Red/System's runtime to cop with printing -2147483648 in commit 3424bcbb in the modified version of your form-signed
function. If you have any proposition to improve my hardcoded version, let me know.
The code looks nice. You will be able to shorten it when c-string! arithmetic will be implemented (should be this week). About the lack of unary minus, there is the NEGATE macro defined in %common.reds which can be used as replacement for [0 - ]. So:
can be written:
(NEGATIVE? is another macro)