Page 1 of 1

newLisp doesn't have long long support?

Posted: Wed Aug 23, 2006 4:05 pm
by _ex_
hi again I'm trying to obtain the value of 2 to the exponent 38
this is basic question that can be solved beautifully as:
print( 2 ** 38 ); PERL
puts( 2 ** 38 ) RUBY
print( 2 ^ 38 ) LUA
or as uglier as
System.out.println( Math.round( Math.pow( 2, 38 ) ) ); JAVA

Posted: Wed Aug 23, 2006 4:14 pm
by Lutz
http://newlisp.org/downloads/newlisp_manual.html#pow

and see also here for quick overview of functions available in newLISP in differewnt groups:

http://newlisp.org/downloads/newlisp_ma ... #functions

Lutz

Posted: Wed Aug 23, 2006 4:17 pm
by _ex_
Of course i'm trying:
(println (floor (pow 2 38)))
2.748779069e+011
Not the exact answer:
274877906944

Posted: Wed Aug 23, 2006 5:13 pm
by cormullion

Code: Select all

(set 'a-large-number (pow 2 38))
(set 'an-even-larger-number (add 1 a-large-number))
(println (format "%20.f" a-large-number) (format "%20.f" an-even-larger-number))(println (format "%20.f" (mul a-large-number an-even-larger-number)))

Posted: Wed Aug 23, 2006 5:28 pm
by Lutz
The next development version 8.9.7 to be released this Friday or Saturday has 64 bit long long support for all integer operations with 19 digits of precision (currently in test). Floats are double 64 bit already.

But as Corumullion has shown, your problem is formatting. If you print without formatting newLISP will choose the "%g" format and give you 9 digits of precision. When formatting right you will have up to 15/16 digits of precision (52bits) when using 64 bit double floats.

Lutz

Posted: Wed Aug 23, 2006 5:31 pm
by Lutz
... you should also read the chapter:
http://newlisp.org/downloads/newlisp_ma ... #int_float

Lutz

Posted: Wed Aug 23, 2006 7:02 pm
by _ex_
thank you guys! :)
I did this for this problem in particular:

Code: Select all

[DON'T LAUGH I'M A NEWBIE....]
(define (double strNumber)

	(setq carry 0)
	(setq strDouble "")
	(reverse strNumber)
	(for (k 0 (- (length strNumber) 1))

		(setq d (- (char strNumber k) (char "0")))
		(setq m	(+ (* d 2) carry))
		(setq md (% m 10))
		(setq strDouble (string md strDouble))
		(setq carry (/ m 10))
	)
	(if (= carry 1)
		(setq strDouble (string carry strDouble))		
	)
	(setq return strDouble)
)

(define (pow2 n)

	(setq strNumber "1")
	(for (k 1 n)
		(setq strNumber (double strNumber))
	)
	(setq return strNumber) 
)

(println (pow2 38))

(exit)
[\DON'T LAUGHT]

Posted: Wed Aug 23, 2006 7:43 pm
by newdep
We never laugh at newby's !! every solution is a working one!! ;-) thats also the power of newlisp !

Welcome btw ;-)

Posted: Wed Aug 23, 2006 9:38 pm
by Lutz
... but just in case you need a shorter solution ;)

Code: Select all

(define (pow2 n) 
    (trim (format "%16.f" (pow 2 n)))) 

(pow2 38) => "274877906944"

(pow2 52) => "4503599627370496"
The last shows the maximum resolution you can have with double floats in newLISP. The 'trim' strips the spaces in front for numbers less than 16 digits.

Lutz

ps: note that in the upcoming development version (pow x) will default to (pow x 2) as suggested by Jeremy Dunn