numeric operation trouble

71 views
Skip to first unread message

Minoru

unread,
Jan 29, 2023, 2:34:14 AM1/29/23
to Extempore
;; How should I do ????
;; I use extempore-v0.8.9-macos-11.0.zip on OS 12.6.3
;; ver 0.70, too.

(= 1.2 (- 61.2 60))          ;f
(= 1.2 (+ 1.1 0.1))          ;f
(= (abs 1.2) (abs (+ 1.1 0.1)))      ;f
(= 2 2.0)   ;t
(= 2.2 2.2) ;t
(= (+ 2 .2) 2.2)      ;t
(= 1.1 (- 61.1 60.0)) ;f
(= 3.4 (- 63.5 60.1)) ;f
(= 3.4 (- 63.4 60.0)) ;f
(= 3.4 (+ 3.0 0.4)) ;t
(= 3.4 (+ -63.4 60.0)) ;f
(= 63.1 (+ 63 .1))     ;t

;; I tryed exact->inexact, inexact->exact etc.... but ...

Minoru

unread,
Jan 29, 2023, 2:45:36 AM1/29/23
to Extempore
(modulo 61.2 12) ;1.200000
(= 1.200000 (modulo 61.2 12.0 )) ;f


;;  oh I see, but how should I do, more?

(inexact->exact (modulo 61.2 12.0 )) ;inexact->exact: not integral: 1.20000000000000284217094
(inexact->exact 1.2);inexact->exact: not integral: 1.19999999999999995559108

2023年1月29日日曜日 16:34:14 UTC+9 Minoru:

Minoru

unread,
Jan 29, 2023, 2:56:59 AM1/29/23
to Extempore
;;  Oh I see the way to resolve it !
;;  I remember George's posting !!
;;

(floor (* 100 1.2))                  ;120.00000
(floor (* 100 (modulo 61.2 12.0 ) )) ;120.00000

(= (floor (* 100 1.2)) (floor (* 100 (modulo 61.2 12.0 ) ))) ;t    OK!!!!!

;; though
(modulo 61.2 12.0 )                         ;1.200000
(= 1.2 (modulo 61.2 12.0 ))                     ;f
2023年1月29日日曜日 16:45:36 UTC+9 Minoru:

Minoru

unread,
Jan 29, 2023, 6:42:44 AM1/29/23
to Extempore

;; I could avoid a trouble of "=" number operation when making G-pc:degree func.
;; But there still seems to be some problems......


(= 1.2 (- 61.2 60))   ;f
(= 1.2 (+ 1.1 0.1))   ;f
(= 1.1 (- 61.1 60.0)) ;f
(= 3.4 (- 63.5 60.1)) ;f
(= 1.1 (modulo 61.1 12.0) ) ;f
(= 1.1 1.100000)    ;f

2023年1月29日日曜日 16:56:59 UTC+9 Minoru:

Minoru

unread,
Jan 29, 2023, 7:06:57 AM1/29/23
to Extempore
(member 10 '(1 2 3 10 5))                           ;(10 5)
(member 0.02 '(0 0.01 0.02 0.03 1.2))      ;(0.020000 0.030000 1.200000)
(member 1.2 '(1 1.2 2 3))                            ;(1.200000 2 3)
(modulo 61.2 12)                                         ;1.2
(member (modulo 61.2 12) '(1 1.2 2 3))  ;#f

2023年1月29日日曜日 20:42:44 UTC+9 Minoru:

Minoru

unread,
Jan 29, 2023, 7:53:47 AM1/29/23
to Extempore
George

You wrote,
>The culprit turns out to be the built-in "member" function in the definition of pc:? At line 275.
>Because "member" can't handle non-integer numbers .....

But a real person of interest seems to be someone else ....

(member 0.02 '(0 0.01 0.02 0.03 1.2))      ;(0.020000 0.030000 1.200000)
(member 1.2 '(1 1.2 2 3))                            ;(1.200000 2 3)
(modulo 61.2 12)                                         ;1.2
(member (modulo 61.2 12) '(1 1.2 2 3))  ;#f

2023年1月29日日曜日 21:06:57 UTC+9 Minoru:

Minoru

unread,
Jan 31, 2023, 2:27:50 AM1/31/23
to Extempore
;; I could recall something about computer numeric calculation ....
;; decimal.. binary... decimals... calculation accuracy.. error ...
;; internal representation, etc, etc, yes, I have read
;; something like that though long before ......
;; But I have never get any education for computer science, so something lacks.

;; Then I happend to find out making it integer and round it,
;; this way seems to be populer one, I knew it after it,
;; and there seems to be another one,
;; the difference of 2 numbers is less than the criteria number,
;; 0,01 or 0,001 or any accuracy you need,
;; when processing decimal fraction ....

;; Oh, I remember Excel func,  round(n, number of decimal places), too.
;; then ...

(define round-n
   (lambda (n dec-n)
      (let ((expt-n (expt 10 dec-n)))
          (/ (round (* n expt-n)) expt-n))))

(round-n 10.1 1)   ;10.100000
(round-n 10.123 1) ;10.100000
(round-n 10.123 2) ;10.120000
(round-n 10.125 2) ;10.120000  using 'round func
(round-n 10.115 2) ;10.120000  using 'round func
(round-n 10.125 3) ;10.125000


(= 1.23 (- 61.23 60)) ; #f
(- 61.23 60) ; 1.230000
(= 1.230000 (- 61.23 60)) ; #f
(= 1.230000 (- 61.230000 60)) ; #f
(= (round-n 1.23 2) (round-n (- 61.23 60) 2)) ; #t
(= (round-n 1.235 2) (round-n (- 61.235 60) 2)) ;f
(= (round-n 1.235 2) (round-n (- (round-n 61.235 2) 60) 2)) ;t
(= (round-n 1.235 2) (round-n (- (round-n 61.235 2) (round-n 60 2)) 2)) ;t

(modulo 63.35765 12) ; 3.357650
(= 3.357650 (modulo 63.357650 12)) ;f
(= (round-n 3.357650 6) (round-n (modulo 63.357650 12) 6)) ;t
(= (round-n 3.357650 3) (round-n (modulo 63.357650 12) 3)) ;t

;; 'round-n seems to be ok for the purpose so far
;; there must be library or something that is much better though ....

;; And another one,

(define =round
    (lambda (n1 n2 dec-n)
        (< (abs (- n1 n2)) (/ 1 (expt 10 dec-n)))))

(- 61.23 60) ; 1.230000
(= 1.230000 (- 61.230000 60.000000)) ; f
(= 1.23 (- 61.23 60)) ; f
(=round 1.23 (- 61.23 60) 2) ;t
(=round 1.234 (- 61.239 60) 2) ;t
(=round 1.234 (- 61.239 60) 3) ;f

(modulo 63.35765 12) ; 3.357650
(= 3.357650 (modulo 63.357650 12)) ;f
(=round 3.357650 (modulo 63.357650 12) 3) ;t
(=round 3.357850 (modulo 63.357650 12) 4) ;f
(=round 3.357650 (modulo 63.357850 12) 4) ;f

;; this seems to be ok, too ...

;; Regards

2023年1月29日日曜日 21:53:47 UTC+9 Minoru:

Michele Pasin

unread,
Feb 14, 2023, 4:26:29 AM2/14/23
to extemp...@googlegroups.com
Hi Minoru

Maybe you can try to do that using Extempore's own language xtlang instead of scheme. 

Eg I just tried eq_float_equal, taken from this example: https://github.com/digego/extempore/blob/v0.8.9/examples/core/typeclasses.xtm#L219

```
(bind-func eq_float_equal
  (lambda (a:float b:float)
    (= a b)))

(eq_float_equal 1.2 (- 61.2 60)) ; => 1
(eq_float_equal 1.1 (- 61.2 60)) ; => 0
```

There might be a way to do that using scheme only.. if I find it I'll let you know :-) 

---
michele 

--
You received this message because you are subscribed to the Google Groups "Extempore" group.
To unsubscribe from this group and stop receiving emails from it, send an email to extemporelan...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/extemporelang/78e66129-0285-4bec-8080-de6e69bce52fn%40googlegroups.com.

Minoru

unread,
Feb 14, 2023, 9:38:15 AM2/14/23
to Extempore
 Hi Michele

;; Thank you so much for your suggestions ....
;; I tried them ... and results were .... unfortunately, not resolved enough yet ...
;; so, let me know please, if you find anything else ....

;; A
(/ 1. 3.)                   ;0.333333
(eq_float_equal (/ 1. 3.) 0.333333)    ;0
(eq_float_equal 0.333333 (/ 1. 3.))    ;0

;; but I found div in that file, too  ....
(eq_float_equal ($ (div 1. 3.)) 0.333333) ;1

(= ($ (div 1. 3.)) 0.333333) ;t
(= ($ (div 1. 3.)) 0.3333) ;f

;; and this seems not bad, too ...
(=round 0.333333 (/ 1. 3.) 4) ;t
(=round 0.333333 (/ 1. 3.) 5) ;t
(=round 0.333333 (/ 1. 3.) 6) ;t
(=round 0.333332 (/ 1. 3.) 6) ;f


;; B
(= (* (/ 1.0 3.57) 3.) (/ (* 1. 3.) 3.57) )  ;t !
(* (/ 1.0 3.57) 3.)  ;0.840336
(/ (* 1. 3.) 3.57)   ;0.840336

(= (* (/ 1.0 3.57) 3.) 0.840336 ) ;f
(eq_float_equal (* (/ 1.0 3.57) 3.) 0.840336 ) ;0
;; but this is ok
(=round (* (/ 1.0 3.57) 3.) 0.840336 6)           ;t !

;; C
(/ 1.0 3.0)    ;0.333333
(* 0.333333 3.) ;0.999999
;; then this is very interesting !! it seems like a human intelligence ???
;; why possible ?  computer science/education teaches this or mathxxxxx problem ?
(* (/ 1.0 3.0) 3.) ;1.000000  !!  wow !!

(num_f64_div 1. 3.) ;0.333333
(= (num_f64_div 1.0 3.) 0.333333) ;f
(= (/ 1.0 3.0) (/ 1.0 3.0))      ;t
(= (num_f64_div 1.0 3.) 0.333333) ;f
(eq_float_equal (num_f64_div 1.0 3.) 0.333333) ;0
(eq_float_equal (/ 1.0 3.) 0.333333) ;0

;; and this is ok
(eq_float_equal ($ (div 1.0 3.)) 0.333333) ;1
(=round (/ 1.0 3.) 0.333333 6)      ;t


;; D
;; it seems to be ok but always.....
;;    'Ambiguous or unavailable xtlang wrapper: "xtm_equal"'
(xtm_equal 1. 1.) ;t
(xtm_equal 1 1)      ;t

(xtm_equal (/ 1. 3. ) 0.333333) ;t

Regards
2023年2月14日火曜日 18:26:29 UTC+9 michel...@gmail.com:

Minoru

unread,
Feb 14, 2023, 9:55:10 AM2/14/23
to Extempore
Hi Michele

>> There might be a way to do that using scheme only.. 

Yes I thought it,  too, there must be some library or something about these problems in scheme/lisp or the other languages, too.

2023年2月14日火曜日 23:38:15 UTC+9 Minoru:

Minoru

unread,
Feb 14, 2023, 11:45:03 PM2/14/23
to Extempore
 Hi michele

;; These are some hints ???

(/ 1.0 3.0)    ;0.333333
(* 0.333333 3.0) ;0.999999
(* (/ 1.0 3.0) 3.0) ;1.000000  !!  wow !! why ???

;; then I found & remembered ....
(/ 1 3) ;1/3 !!
(/ 1 2) ;1/2
(* 1/3 3) ;1/1
(* (/ 1 3) 3) ; 1/1,    it seems that this is answer, using fraction !

;; but ...
(/ 1.0 3.0) ;0.333333
1/3        ;ok,  returns 1/3
1.0/3.0        ; error,   eval: unbound variable: 1.0/3.0

;; where is answer ??

2023年2月14日火曜日 23:55:10 UTC+9 Minoru:

Ross Bencina

unread,
Feb 18, 2023, 1:10:17 AM2/18/23
to extemp...@googlegroups.com

Hi Minoru,

Rational numbers and IEEE 754 floating point numbers are not the same
thing. You need to be clear on whether:

(/ 1.0 3.0)
(/ 1 3)

are constructors for arbitrary precision rational numbers, or function
invocations that compute floating point numbers. My understanding is
that Scheme supports both of these number systems, but I don't know how
this works in Extempore. So I can't really explain all of your test
cases, but I can see one thing that's confusing you because it confuses
everyone when they start to deal with non-integer numbers in a computer.

What you're observing is analogous to using a finite number of decimal
digits (decimal "fixed point"). Here is an example:

Speaking purely mathematically here, if we insist on limiting all
intermediate results to 3 digits past the decimal point, then

1/3 evaluates to 0.333

therefore

3(1/3) = 3(0.333) = 0.999 != 1

and this should not be surprising.

Now back to computers, IEEE 754 floating point arithmetic[1], which uses
a fixed number of binary digits for its representaion (typically 32 or
64 bits per number), can not precisely represent all rational numbers
(let-alone non-rational numbers such as pi and e). One consequence is
that the floating point result of dividing two exactly represented
numbers a and b is not necessarily equal to the exactly represented
rational number a/b, or as you're observing, b*(a/b) is not equal to a
(because the float "a/b" is not equal to the rational a/b). This is due
to the same kind of truncation effect as in the example with 1/3 and 0.333.

The following text is the standard background reading:

What Every Computer Scientist Should Know About Floating-Point
Arithmetic, by David Goldberg.

https://www.itu.dk/~sestoft/bachelor/IEEE754_article.pdf

Also, you need to be careful about the difference between the binary
representation stored in the computer memory and what is printed on
screen as decimal digits. For example just as there is no finite
representation of the rational number 1/3 using only decimal digits,
there are many IEEE 754 numbers that have no finite decimal
representation. So what you're looking at on the screen is usually a
decimal approximation of the actual number in memory. (That said, there
is at least one minimal, finite decimal representation that will be
correctly rounded to each floating point number [2] and most languages
use routines that produce and consume these minimal representations [3],
even if the C runtime does not[4]).

"The value 0.1f is a simple example of the distinction. 0.1f uniquely
identifies a particular float (the float whose value is closest), but
the value of this float isn’t 0.1 – it is actually
0.100000001490116119384765625. Close, but different." (ibid.)

Kind regards,

Ross.


[1] https://en.wikipedia.org/wiki/IEEE_754

[2] See for example the papers given in the "References" section here:
https://www.ryanjuckett.com/printing-floating-point-numbers/

[3] https://netlib.org/fp/

[4]
https://randomascii.wordpress.com/2013/02/07/float-precision-revisited-nine-digit-float-portability/

(see
> <https://extemporelang.github.io/docs/reference/types/>
> instead of scheme.
>
> Eg I just tried *eq_float_equal, *taken from this example:
>
https://github.com/digego/extempore/blob/v0.8.9/examples/core/typeclasses.xtm#L219
>
> ```
> (bind-func eq_float_equal
> (lambda (a:float b:float)
> (= a b)))
>
> (eq_float_equal 1.2 (- 61.2 60)) ; => 1
> (eq_float_equal 1.1 (- 61.2 60)) ; => 0
> ```
>
> Also might be worth looking unto *xtm_equal* =>
<https://groups.google.com/d/msgid/extemporelang/78e66129-0285-4bec-8080-de6e69bce52fn%40googlegroups.com?utm_medium=email&utm_source=footer>.
>
> --
> You received this message because you are subscribed to the Google
Groups "Extempore" group.
> To unsubscribe from this group and stop receiving emails from it,
send an email to extemporelan...@googlegroups.com
<mailto:extemporelan...@googlegroups.com>.
> To view this discussion on the web visit
https://groups.google.com/d/msgid/extemporelang/f54ee093-7cd2-484a-81ad-31d99262d4e4n%40googlegroups.com
<https://groups.google.com/d/msgid/extemporelang/f54ee093-7cd2-484a-81ad-31d99262d4e4n%40googlegroups.com?utm_medium=email&utm_source=footer>.

Minoru

unread,
Feb 22, 2023, 11:17:47 PM2/22/23
to Extempore
Hi Ross,

Thank you very much for your concise advices and references,
I remembered or recognized that there were such things in the computer world,
then I have been reading some documents about such theme because it
is necessary for me to know something more before reading references
you wrote.


>> Now back to computers, IEEE 754 floating point arithmetic[1], which uses
>> a fixed number of binary digits for its representaion (typically 32 or
>> 64 bits per number), can not precisely represent all rational numbers

>> one thing that's confusing you because it confuses
>> everyone when they start to deal with non-integer numbers in a computer.

>> What you're observing is analogous to using a finite number of decimal
>> digits (decimal "fixed point").

Yes, I remembered what you pointed out, though not so exact things, of course,
when I found these....

(inexact->exact (modulo 61.2 12.0 )) ;inexact->exact: not integral: 1.20000000000000284217094
(inexact->exact 1.2);inexact->exact: not integral: 1.19999999999999995559108


You wtote these ....


>> 3(1/3) = 3(0.333) = 0.999 != 1
>> and this should not be surprising.

Yes, I think it is not surprising at all because I remembered
somehow about the computer numerical calculation/operation....
maybe, just even the operation order makes differences of the results, too ...
due to rounding etc, error and precision etc, binary and decimal etc ....
round to even .......

but I found these .. now, some of these examples are surprising
and interesting for me after remembering/knowing something like
above, that is, limitation/errors of computation,
(/ 1 3) ; 1/3

(* (/ 1 3) 3) ;1/1
(/ 1.0 3.0)   ;0.333333
(* 3 (/ 1.0 3.0)) ;1.000000  wow!
(* 3.0 (/ 1.0 3.0)) ;1.000000  wow!
(= (* 3 (/ 1.0 3.0))  1.0)   ;t !
(= (* 3.0 (/ 1.0 3.0))  1.0) ;t !

(* 3 1/3) ;1/1
(= (* 3 1/3) 1) ;t
(= (* 3 1/3) 1.) ;t
(= (* 3. 1/3) 1.) ;t
(= (* 3. 0.333) 1.) ;f
(= (* 3. 0.33333333333333333333333333333333) 1.) ;t  wow !
     (* 3. 0.33333333333333333333333333333333)     ;1.000000   wow !!!

(= (* 3. 0.333333333333333) 1.) ;f
     (* 3. 0.333333333333333)     ;1.000000  ????

(= (* 3. 0.3333333333333333) 1.) ;t, oh this seems critical line ....
     (* 3. 0.3333333333333333)     ;1.000000   !

maybe this number of digit indicates something important ???
changing binary floating point to decimal one ???
just a shot in the dark ....  maybe no relations ????

(* 3. 0.333)      ;0.999999
(* 3. 0.333333)   ;0.999999
(* 3. 0.3333333)  ;1.000000
but, of course ....
(= (* 3. 0.3333333) 1.0) ;f

(= (/ 1. 3.) (/ 1 3)) ;t
(= (/ 1. 3.) 1/3) ;t

and
(= 0.1 (+ 0.1 0.0)); t
(= 0.2 (+ 0.1 0.1)); t
(= 0.3 (+ 0.1 0.1 0.1)) ;f
(inexact->exact 0.1);inexact->exact: not integral: 0.10000000000000000555112

(+ 0.10000000000000000555112 0.10000000000000000555112 ) ;0.2000000
(= 0.2 (+ 0.10000000000000000555112 0.10000000000000000555112 )) ;t

(+ 0.10000000000000000555112 0.10000000000000000555112 0.10000000000000000555112) ;0.3000000
(= 0.3 (+ 0.10000000000000000555112 0.10000000000000000555112 0.10000000000000000555112)) ;f
(= 0.10000000000000000555112 0.10000000000000000555112) ;t
(= 0.10000000000000000 0.10000000000000000555112)       ;t
(= 0.1 0.10000000000000000555112)       ;t
(= 0.3 (+ 0.1 0.1 0.1)) ;f
(= (* 0.10000000000000000555112 3)
    (+ 0.10000000000000000555112 0.10000000000000000555112 0.10000000000000000555112)) ;t
(= (* 0.1 3.0)
     (+ 0.10000000000000000555112 0.10000000000000000555112 0.10000000000000000555112)) ;t
(= (* 0.1 3.0) (+ 0.1 0.1 0.1)) ; t
(= 0.3 (+ 0.1 0.1 0.1)) ;f
(= (* 1.0 0.3) (+ 0.1 0.1 0.1)) ;f
(= (* 0.1 3.0) (+ 0.1 0.1 0.1)) ;t


(= 3/10 (+ 1/10 1/10 1/10))   ;t
(+ 1/10 1/10 1/10) ; 3/10
1/10               ;1/10
(= .3 (+ 1/10 1/10 1/10))   ;t
(= .300000000000000002 (+ 1/10 1/10 1/10))   ;t


maybe, due to binary <--> decimal, finite number of digits,
significand, nomalization etc etc ....
and finally, it depends on how extempore implements those .....

I don't understand them so completely, but maybe grasp the gist
and the the consequences .... the variety of them ...
therefore, I will return to my routin work now,
making the music by this extempore with these knowledges .....


Ross, I appreciate your advices very much, thank you again.

2023年2月18日土曜日 15:10:17 UTC+9 Ross Bencina:
Reply all
Reply to author
Forward
0 new messages