2024-05-01 09:48:09 +02:00
|
|
|
// Copyright (c) 2024 Celestino Amoroso (celestino.amoroso@gmail.com).
|
|
|
|
// All rights reserved.
|
|
|
|
|
|
|
|
// operand-fraction.go
|
|
|
|
package expr
|
|
|
|
|
2024-05-18 07:07:17 +02:00
|
|
|
//https://www.youmath.it/lezioni/algebra-elementare/lezioni-di-algebra-e-aritmetica-per-scuole-medie/553-dalle-frazioni-a-numeri-decimali.html
|
|
|
|
|
2024-05-01 09:48:09 +02:00
|
|
|
import (
|
2024-05-01 21:49:15 +02:00
|
|
|
"errors"
|
2024-05-01 09:48:09 +02:00
|
|
|
"fmt"
|
|
|
|
)
|
|
|
|
|
|
|
|
// -------- fraction term
|
|
|
|
func newFractionTerm(tk *Token) *term {
|
|
|
|
return &term{
|
|
|
|
tk: *tk,
|
|
|
|
parent: nil,
|
|
|
|
children: make([]*term, 0, 2),
|
|
|
|
position: posInfix,
|
|
|
|
priority: priFraction,
|
|
|
|
evalFunc: evalFraction,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -------- eval func
|
2024-07-09 07:50:06 +02:00
|
|
|
func evalFraction(ctx ExprContext, opTerm *term) (v any, err error) {
|
2024-05-01 09:48:09 +02:00
|
|
|
var numValue, denValue any
|
|
|
|
var num, den int64
|
|
|
|
var ok bool
|
|
|
|
|
2024-07-09 07:50:06 +02:00
|
|
|
if numValue, denValue, err = opTerm.evalInfix(ctx); err != nil {
|
2024-05-01 09:48:09 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
if num, ok = numValue.(int64); !ok {
|
|
|
|
err = fmt.Errorf("numerator must be integer, got %T (%v)", numValue, numValue)
|
2024-05-01 21:49:15 +02:00
|
|
|
return
|
2024-05-01 09:48:09 +02:00
|
|
|
}
|
|
|
|
if den, ok = denValue.(int64); !ok {
|
|
|
|
err = fmt.Errorf("denominator must be integer, got %T (%v)", denValue, denValue)
|
2024-05-01 21:49:15 +02:00
|
|
|
return
|
|
|
|
}
|
|
|
|
if den == 0 {
|
|
|
|
err = errors.New("division by zero")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if den < 0 {
|
|
|
|
den = -den
|
|
|
|
num = -num
|
|
|
|
}
|
2024-12-23 06:59:39 +01:00
|
|
|
if num != 0 {
|
|
|
|
g := gcd(num, den)
|
|
|
|
num = num / g
|
|
|
|
den = den / g
|
|
|
|
if den == 1 {
|
|
|
|
v = num
|
|
|
|
} else {
|
|
|
|
v = &FractionType{num, den}
|
|
|
|
}
|
2024-05-01 21:49:15 +02:00
|
|
|
} else {
|
2024-12-23 06:59:39 +01:00
|
|
|
v = &FractionType{0, den}
|
2024-05-01 21:49:15 +02:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-05-01 09:48:09 +02:00
|
|
|
// init
|
|
|
|
func init() {
|
2024-12-23 06:59:39 +01:00
|
|
|
// registerTermConstructor(SymVertBar, newFractionTerm)
|
|
|
|
registerTermConstructor(SymColon, newFractionTerm)
|
2024-05-01 09:48:09 +02:00
|
|
|
}
|