Skip to content

Instantly share code, notes, and snippets.

@meijeru
Created May 3, 2011 08:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save meijeru/952998 to your computer and use it in GitHub Desktop.
Save meijeru/952998 to your computer and use it in GitHub Desktop.
FORM function in Red/System (improved version)
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
]
@dockimbel
Copy link

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:

if i < 0 [n: true i: 0 - i]

can be written:

if negative? i [n: true i: negate i]

(NEGATIVE? is another macro)

@meijeru
Copy link
Author

meijeru commented May 5, 2011

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.

@meijeru
Copy link
Author

meijeru commented May 5, 2011

More simplfication in the calculation of the bytes for the individual digits. See latest version.

@dockimbel
Copy link

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.

@meijeru
Copy link
Author

meijeru commented May 28, 2011

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.

@dockimbel
Copy link

Function 'form-hex will be surely useful to print memory addresses for debugging purpose.

@PeterWAWood
Copy link

I suspect form-signed may give an incorrect result when printing -2147483648 as the number currently cannot be properly negated.

@dockimbel
Copy link

Peter is right, form-signed -2147483648 gives -./,),(-*,( as result.

@dockimbel
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment