From 61f27d3c2224c8c6f71c9b9755d772c8049ceb57 Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Thu, 10 Sep 2009 13:53:35 -0700 Subject: [PATCH] sample goyacc program R=rsc OCL=34526 CL=34526 --- src/cmd/goyacc/units | 604 +++++++++++++++++++++++++++++++ src/cmd/goyacc/units.y | 802 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1406 insertions(+) create mode 100644 src/cmd/goyacc/units create mode 100644 src/cmd/goyacc/units.y diff --git a/src/cmd/goyacc/units b/src/cmd/goyacc/units new file mode 100644 index 0000000000..bee36492ce --- /dev/null +++ b/src/cmd/goyacc/units @@ -0,0 +1,604 @@ +/ Plan 9's /lib/units +/ http://plan9.bell-labs.com/sources/plan9/lib/units +/ +/ Copyright (C) 2003, Lucent Technologies Inc. and others. All Rights Reserved. +/ Distributed under the terms of the Lucent Public License Version 1.02 +/ See http://plan9.bell-labs.com/plan9/license.html +/ +/order of evaluation +/ + - +/ * / +/ juxtaposition (meaning *) +/ ¹ ² ³ ^ +/ | (meaning /) +/ name number () + +/dimensions +m # +kg # +sec # +coul # +candela # +$ # +radian # +bit # +erlang # +°K # +°C # +°F # + +/constants + +π 3.14159265358979323846 +pi π +c 2.997925e+8 m/sec +g 9.80665 m/sec² +au 1.49597871e+11 m +mole 6.022169e+23 +e 1.6021917e-19 coul +energy c² +force g +mercury 1.33322e+5 kg/m²sec² +hg mercury +h 6.62620e-34 m²kg/sec +ℏ h/2 π +hbar ℏ +nonillion 1e30 +octillion 1e27 +septillion 1e24 +sextillion 1e21 +pentillion 1e18 +quadrillion 1e15 +trillion 1e12 +billion 1e9 +million 1e6 +thousand 1e3 +hundred 1e2 + +/dimensionless + +° 1|180 π radian +degree ° +circle 2 π radian +turn 2 π radian +grad .9 ° +arcdeg 1 ° +arcmin 1|60 ° +arcsec 1|3600 ° +ccs 1|36 erlang + +steradian radian² +sphere 4 π steradian +sr steradian +giga 1024 1024 1024 + +/Time + +second sec +s sec +minute 60 sec +min minute +hour 60 min +hr hour +day 24 hr +da day +week 7 day +year 365.24219879 day +yr year +month 1|12 year +ms millisec +us microsec + +/Mass + +gram millikg +gm gram +mg milligram +metricton kilokg + +/Avoirdupois + +lb .45359237 kg +lbf lb g +pound lb +ounce 1|16 lb +oz ounce +dram 1|16 oz +dr dram +grain 1|7000 lb +gr grain +shortton 2000 lb +ton shortton +longton 2240 lb + +/Apothecary + +scruple 20 grain +apdram 60 grain +apounce 480 grain +troyounce apounce +appound 5760 grain +troypound appound + +/Length + +meter m +cm centimeter +mm millimeter +km kilometer +nm nanometer +micron micrometer +µ micrometer +Å decinanometer +angstrom Å + +inch 2.54 cm +" inch +in inch +inches inch +' 12" +foot 12 in +feet foot +ft foot +yard 3 ft +yd yard +rod 5.5 yd +rd rod +mile 5280 ft +mi mile + +british 1200|3937 m/ft +nmile 1852 m + +acre 4840 yd² + +cc cm³ +liter kilocc +ml milliliter + +/US Liquid + +gallon 231 in³ +imperial 1.20095 +epa 0.8 +gal gallon +quart 1|4 gal +qt quart +pint 1|2 qt +pt pint + +floz 1|16 pt +fldr 1|8 floz + +/US Dry + +dry 268.8025 in³/gallon +peck 8 dry quart +pk peck +bushel 4 peck +bu bushel + +/British + +brgallon 277.420 in³ +brquart 1|4 brgallon +brpint 1|2 brquart +brfloz 1|20 brpint +brpeck 554.84 in³ +brbushel 4 brpeck + +/Energy Work + +newton kg m/sec² +nt newton +joule nt m +cal 4.1868 joule + +/Electrical + +coulomb coul +ampere coul/sec +amp ampere +watt joule/sec +volt watt/amp +Ω volt/amp +ohm Ω +mho 1/Ω +farad coul/volt +henry sec²/farad +weber volt sec + +/Light + +cd candela +lumen cd sr +lux cd sr/m² + +/ MONEY DATE +/ Fri Oct 27 15:52:13 EDT 2000 + +/ MONEY START +argentpeso 1 | .9998 $ +australiadollar 1 | 1.9175 $ +brazilreal 1 | 1.9300 $ +britainpound 1 | .6972 $ +canadadollar 1 | 1.5237 $ +chilepeso 1 | 576.45 $ +chinayuan 1 | 8.2782 $ +colombiapeso 1 | 2165.00 $ +czechrepkoruna 1 | 42.11 $ +denmarkkrone 1 | 9.0134 $ +dominicanpeso 1 | 16.00 $ +egyptpound 1 | 3.6750 $ +euro 1 | 1.08863 $ +hongkongdollar 1 | 7.7991 $ +hungaryforint 1 | 317.59 $ +indiarupee 1 | 46.600 $ +indnsiarupiah 1 | 9025.00 $ +israelshekel 1 | 4.1450 $ +japanyen 1 | 108.34 $ +jordandinar 1 | .71098 $ +lebanonpound 1 | 1514.00 $ +malaysiaringgit 1 | 3.7996 $ +mexicopeso 1 | 9.6850 $ +newzealanddollar 1 | 2.4938 $ +norwaykrone 1 | 9.5940 $ +pakistanrupee 1 | 57.75 $ +perunewsol 1 | 3.510 $ +philpinspeso 1 | 50.10 $ +polandzloty 1 | 4.70 $ +russiaruble 1 | 27.9200 $ +sdr 1 | .7841 $ +saudiarabriyal 1 | 3.7508 $ +singaporedollar 1 | 1.7546 $ +slovakrepkoruna 1 | 52.65 $ +southafricarand 1 | 7.6725 $ +southkoreawon 1 | 1137.20 $ +swedenkrona 1 | 10.2621 $ +switzerlndfranc 1 | 1.8195 $ +taiwandollar 1 | 32.09 $ +thailandbaht 1 | 43.58 $ +turkeylira 1 | 687860 $ +uaedirham 1 | 3.6728 $ +uruguaynewpeso 1 | 12.4180 $ +venezuelabolivar 1 | 693.2500 $ +/ MONEY END + +€ euro +£ britainpound +¥ japanyen +dollar $ + +bef 1 | 40.3399 € +belgiumfranc bef +dem 1 | 1.95583 € +germanymark dem +grd 1 | 340.750 € +greecedrachma grd +esp 1 | 166.386 € +spainpeseta esp +frf 1 | 6.55957 € +francefranc frf +iep 1 | .787564 € +irelandpunt iep +itl 1 | 1936.27 € +italylira itl +luf 1 | 40.3399 € +luxembourgfranc luf +nlg 1 | 2.20371 € +netherlandsguilder nlg +ats 1 | 13.7603 € +austriaschilling ats +pte 1 | 200.482 € +portugalescudo pte +fim 1 | 5.94573 € +finlandmark fim + +baht thailandbaht +bolivar venezuelabolivar +brpound britainpound +dinar jordandinar +dirham uaedirham +drachma greecedrachma +escudo portugalescudo +forint hungaryforint +franc francefranc +guilder netherlandsguilder +krona swedenkrona +lira italylira +mark germanymark +peseta spainpeseta +peso mexicopeso +punt irelandpunt +rand southafricarand +real brazilreal +yuan chinayuan +ringgit malaysiaringgit +riyal saudiarabriyal +ruble russiaruble +rupee indiarupee +rupiah indnsiarupiah +shekel israelshekel +sol perunewsol +won southkoreawon +yen japanyen +zloty polandzloty + +usdollar dollar +sterling britainpound | pound +poundsterling britainpound + +/bits + +baud bit/sec +byte 8 bit +short 2 byte +long 4 byte +vlong 8 bytes +frame 2352 byte + +/Australian liquid measure + +pony 7 brfloz +midie 10 brfloz +pot midie +handle midie +schooner 15 brfloz +jug 40 brfloz +resch midie +alf midie +tinny 13 brfloz +stubby tinny +twisty 250 ml +longneck 2 tinny +slab 24 tinny +sixpack 6 tinny +nip brfloz + +/wine +winebottle 750 ml +balthazar 16 winebottle +jeroboam 4 winebottle +magnum 2 winebottle +mathusalem 8 winebottle +methuselah 8 winebottle +nebuchadnezzar 20 winebottle +rehoboam 6 winebottle +salmanazar 12 winebottle +split 0.25 winebottle +jigger 1.5 floz + +/Trivia + +% 1|100 +admiraltyknot 6080 ft/hr +ε₀ (1e-9/36π) farad/m +α (1/4π ε₀) e²/ℏ c +alpha α +apostilb cd/π m² +are 1e+2 m² +arpentcan 27.52 mi +arpentlin 191.835 ft +astronomicalunit au +atmosphere 1.01325e+5 nt/m² +atm atmosphere +atomicmassunit 1.66044e-27 kg +amu atomicmassunit +bag 94 lb +bakersdozen 13 +bar 1e+5 nt/m² +barie 1e-1 nt/m² +barleycorn 1|3 in +barn 1e-28 m² +barrel 42 gal +barye 1e-1 nt/m² +bev 1e+9 e volt +biot 10 amp +blondel cd/π m² +boardfoot 144 in³ +bolt 40 yd +bottommeasure 1|40 in +britishthermalunit 1.05506e+3 joule +btu britishthermalunit +quad 1.0e+15 btu +refrigeration 12000 btu/ton hour +buck dollar +cable 720 ft +caliber 1e-2 in +calorie cal +carat 205 mg +cent centidollar +cental 100 lb +centesimalminute 1e-2 grad +centesimalsecond 1e-4 grad +century 100 year +cfs ft³/sec +chain 66 ft +circularinch 1|4 π in² +circularmil 1e-6|4 π in² +clusec 1e-8 mm hg m³/s +coomb 4 bu +cord 128 ft³ +cordfoot cord +crith 9.06e-2 gm +cubit 18 in +cup 1|2 pt +curie 3.7e+10/sec +cusec ft³/sec +dalton amu +decade 10 yr +degK °K +degC °C +degF °F +dipotre 1/m +displacementton 35 ft³ +doppelzentner 100 kg +dozen 12 +drop .03 cm³ +dyne cm gm/sec² +electronvolt e volt +ell 45 in +engineerschain 100 ft +engineerslink 100|100 ft +equivalentfootcandle lumen/π ft² +equivalentlux lumen/π m² +equivalentphot cd/π cm² +erg cm²gm/sec² +ev e volt +faraday 9.652e+4 coul +fathom 6 ft +fermi 1e-15 m +fifth 4|5 qt +fin 5 dollar +finger 7|8 in +firkin 9 gal +footcandle lumen/ft² +footlambert cd/π ft² +fortnight 14 da +franklin 3.33564e-10 coul +frigorie kilocal +furlong 220 yd +galileo 1e-2 m/sec² +gamma 1e-9 weber/m² +gauss 1e-4 weber/m² +geodeticfoot british ft +geographicalmile 1852 m +gilbert 7.95775e-1 amp +gill 1|4 pt +gross 144 +gunterschain 22 yd +hand 4 in +hectare 1e+4 m² +hefnercandle .92 cd +hertz 1/sec +hogshead 2 barrel +hd hogshead +homestead 1|4 mi² +horsepower 550 ft lb g/sec +hp horsepower +hyl gm force sec²/m +hz 1/sec +imaginarycubicfoot 1.4 ft³ +karat 1|24 +kcal kilocal +kcalorie kilocal +kev 1e+3 e volt +key kg +khz 1e+3/sec +kilderkin 18 gal +knot nmile/hr +kwh kilowatt hour +lambert cd/π cm² +langley cal/cm² +last 80 bu +league 3 mi +lightyear c yr +ly lightyear +lightsecond c sec +line 1|12 in +link 66|100 ft +longhundredweight 112 lb +longquarter 28 lb +lusec 1e-6 mm hg m³/s +mach 331.46 m/sec +marineleague 3 nmile +maxwell 1e-8 weber +metriccarat 200 mg +mev 1e+6 e volt +mgd megagal/day +mh millihenry +mhz 1e+6/sec +mil 1e-3 in +millenium 1000 year +minersinch 1.5 ft³/min +minim 1|60 fldr +mo month +mpg mile/gal +mph mile/hr +nail 1|16 yd +nauticalmile nmile +nit cd/m² +noggin 1|8 qt +nox 1e-3 lux +ns nanosec +oersted 2.5e+2 amp/m π +oe oersted +pace 36 in +palm 3 in +parasang 3.5 mi +parsec au radian/arcsec +pascal nt/m² +pc parsec +pennyweight 1|20 oz +percent % +perch rd +pf picofarad +phot lumen/cm² +pica 1|6 in +pieze 1e+3 nt/m² +pipe 4 barrel +point 1|72 in +poise gm/cm sec +pole rd +poundal ft lb/sec² +pdl poundal +proof 1/200 +psi lb g/in² +quarter 9 in +quartersection 1|4 mi² +quintal 100 kg +quire 25 +rad 100 erg/gm +ream 500 +registerton 100 ft³ +rhe 10 m²/nt sec +rontgen 2.58e-4 curie/kg +rood 1.21e+3 yd +rope 20 ft +rutherford 1e+6/sec +rydberg 1.36054e+1 ev +sabin 1 ft² +sack 3 bu +seam 8 bu +section mi² +shippington 40 ft³ +shorthundredweight 100 lb +shortquarter 25 lb +siemens 1/Ω +σ 5.66956e-5 erg/cm² °K^4 sec +sigma σ +skein 120 yd +skot 1e-3 apostilb +slug lb g sec²/ft +span 9 in +spat 4 π sr +spindle 14400 yd +square 100 ft² +squidge 1|972 inch +catsquidge 1|432 inch +stere m³ +sthene 1e+3 nt +stilb cd/cm² +stoke 1e-4 m²/sec +stone 14 lb +strike 2 bu +surveyfoot british ft +surveyorschain 66 ft +surveyorslink 66|100 ft +tablespoon 4 fldr +teaspoon 4|3 fldr +tesla weber/m² +therm 1e+5 btu +thermie 1e+6 cal +timberfoot ft³ +tnt 4.6e+6 m²/sec² +tonne 1e+6 gm +torr mm hg +township 36 mi² +tun 8 barrel +water .22491|2.54 kg/m²sec² +wey 40 bu +weymass 252 lb +Xunit 1.00202e-13 m +k 1.38047e-16 erg/°K +foal 9223372036854775807 diff --git a/src/cmd/goyacc/units.y b/src/cmd/goyacc/units.y new file mode 100644 index 0000000000..a5510fbca6 --- /dev/null +++ b/src/cmd/goyacc/units.y @@ -0,0 +1,802 @@ +// Derived from Plan 9's /sys/src/cmd/units.y +// http://plan9.bell-labs.com/sources/plan9/sys/src/cmd/units.y +// +// Copyright (C) 2003, Lucent Technologies Inc. and others. All Rights Reserved. +// Portions Copyright 2009 The Go Authors. All Rights Reserved. +// Distributed under the terms of the Lucent Public License Version 1.02 +// See http://plan9.bell-labs.com/plan9/license.html + +%{ + +// units.y +// example of a goyacc program +// usage is +// goyacc units.y (produces y.go) +// 6g y.go +// 6l y.6 +// ./6.out $GOROOT/src/cmd/goyacc/units +// you have: c +// you want: furlongs/fortnight +// * 1.8026178e+12 +// / 5.5474878e-13 +// you have: + +import +( + "flag"; + "io"; + "fmt"; + "bufio"; + "os"; + "math"; + "strconv"; + "utf8"; +) + +const +( + Ndim = 15; // number of dimensions + Maxe = 695; // log of largest number +) + +type Node +struct +{ + vval float64; + dim [Ndim]int8; +} + +type Var +struct +{ + name string; + node Node; +} + +var fi *bufio.Reader // input +var fund [Ndim]*Var // names of fundamental units +var line string // current input line +var lineno int // current input line number +var linep int // index to next rune in unput +var nerrors int // error count +var one Node // constant one +var peekrune int // backup runt from input +var retnode1 Node +var retnode2 Node +var retnode Node +var sym string +var vflag bool + +%} + +%union +{ + node Node; + vvar *Var; + numb int; + vval float64; +} + +%type prog expr expr0 expr1 expr2 expr3 expr4 + +%token VAL +%token VAR +%token SUP +%% +prog: + ':' VAR expr + { + var f int; + + f = int($2.node.dim[0]); + $2.node = $3; + $2.node.dim[0] = 1; + if f != 0 { + Error("redefinition of %v", $2.name); + } else + if vflag { + fmt.Printf("%v\t%v\n", $2.name, &$2.node); + } + } +| ':' VAR '#' + { + var f, i int; + + for i=1; i= Ndim { + Error("too many dimensions"); + i = Ndim-1; + } + fund[i] = $2; + + f = int($2.node.dim[0]); + $2.node = one; + $2.node.dim[0] = 1; + $2.node.dim[i] = 1; + if f != 0 { + Error("redefinition of %v", $2.name); + } else + if vflag { + fmt.Printf("%v\t#\n", $2.name); + } + } +| ':' + { + } +| '?' expr + { + retnode1 = $2; + } +| '?' + { + retnode1 = one; + } + +expr: + expr4 +| expr '+' expr4 + { + add(&$$, &$1, &$3); + } +| expr '-' expr4 + { + sub(&$$, &$1, &$3); + } + +expr4: + expr3 +| expr4 '*' expr3 + { + mul(&$$, &$1, &$3); + } +| expr4 '/' expr3 + { + div(&$$, &$1, &$3); + } + +expr3: + expr2 +| expr3 expr2 + { + mul(&$$, &$1, &$2); + } + +expr2: + expr1 +| expr2 SUP + { + xpn(&$$, &$1, $2); + } +| expr2 '^' expr1 + { + var i int; + + for i=1; i= Ndim { + i = int($3.vval); + if float64(i) != $3.vval { + Error("exponent not integral"); + } + xpn(&$$, &$1, i); + } + } + +expr1: + expr0 +| expr1 '|' expr0 + { + div(&$$, &$1, &$3); + } + +expr0: + VAR + { + if $1.node.dim[0] == 0 { + Error("undefined %v", $1.name); + $$ = one; + } else + $$ = $1.node; + } +| VAL + { + $$ = one; + $$.vval = $1; + } +| '(' expr ')' + { + $$ = $2; + } +%% + +func +Lex() int +{ + var c, i int; + + c = peekrune; + peekrune = ' '; + +loop: + if (c >= '0' && c <= '9') || c == '.' { + goto numb; + } + if ralpha(c) { + goto alpha; + } + switch c { + case ' ', '\t': + c = getrune(); + goto loop; + case '×': + return '*'; + case '÷': + return '/'; + case '¹', 'ⁱ': + yylval.numb = 1; + return SUP; + case '²', '⁲': + yylval.numb = 2; + return SUP; + case '³', '⁳': + yylval.numb = 3; + return SUP; + } + return c; + +alpha: + sym = ""; + for i=0;; i++ { + sym += string(c); + c = getrune(); + if !ralpha(c) { + break; + } + } + peekrune = c; + yylval.vvar = lookup(0); + return VAR; + +numb: + sym = ""; + for i=0;; i++ { + sym += string(c); + c = getrune(); + if !rdigit(c) { + break; + } + } + peekrune = c; + f, err := strconv.Atof64(sym); + if err != nil { + fmt.Printf("error converting %v", sym); + f = 0; + } + yylval.vval = f; + return VAL; +} + +func +main() +{ + var file string; + + flag.BoolVar(&vflag, "v", false, "verbose"); + + flag.Parse(); + + file = "units"; + if flag.NArg() > 0 { + file = flag.Arg(0); + } + + f,err := os.Open(file, os.O_RDONLY, 0); + if err != nil { + fmt.Printf("error opening %v: %v", file, err); + os.Exit(1); + } + fi = bufio.NewReader(f); + + one.vval = 1; + + /* + * read the 'units' file to + * develope a database + */ + lineno = 0; + for { + lineno++; + if readline() { + break; + } + if len(line) == 0 || line[0] == '/' { + continue; + } + peekrune = ':'; + Parse(); + } + + /* + * read the console to + * print ratio of pairs + */ + fi = bufio.NewReader(os.NewFile(0, "stdin")); + + lineno = 0; + for { + if (lineno & 1) != 0 { + fmt.Printf("you want: "); + } else + fmt.Printf("you have: "); + if readline() { + break; + } + peekrune = '?'; + nerrors = 0; + Parse(); + if nerrors != 0 { + continue; + } + if (lineno & 1) != 0 { + if specialcase(&retnode, &retnode2, &retnode1) { + fmt.Printf("\tis %v\n", &retnode); + } else { + div(&retnode, &retnode2, &retnode1); + fmt.Printf("\t* %v\n", &retnode); + div(&retnode, &retnode1, &retnode2); + fmt.Printf("\t/ %v\n", &retnode); + } + } else + retnode2 = retnode1; + lineno++; + } + fmt.Printf("\n"); + os.Exit(0); +} + +/* + * all characters that have some + * meaning. rest are usable as names + */ +func +ralpha(c int) bool +{ + switch c { + case 0, '+', '-', '*', '/', '[', ']', '(', ')', + '^', ':', '?', ' ', '\t', '.', '|', '#', + '×', '÷', '¹', 'ⁱ', '²', '⁲', '³', '⁳': + return false; + } + return true; +} + +/* + * number forming character + */ +func +rdigit(c int) bool +{ + switch c { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '.', 'e', '+', '-': + return true; + } + return false; +} + +func +Error(s string, v ...) +{ + + /* + * hack to intercept message from yaccpar + */ + if s == "syntax error" { + Error("syntax error, last name: %v", sym); + return; + } + fmt.Printf("%v: %v\n\t", lineno, line); + fmt.Printf(s, v); + fmt.Printf("\n"); + + nerrors++; + if nerrors > 5 { + fmt.Printf("too many errors\n"); + os.Exit(1); + } +} + +func +add(c,a,b *Node) +{ + var i int; + var d int8; + + for i=0; i 0 { + str = printdim(str, i, d); + } else + if d < 0 { + f = 1; + } + } + + if f != 0 { + str += " /"; + for i=1; i= len(line) { + return 0; + } + c,n = utf8.DecodeRuneInString(line[linep:len(line)]); + linep += n; + if c == '\n' { + c = 0; + } + return c; +} + +var symmap = make(map[string]*Var); // symbol table + +func +lookup(f int) *Var +{ + var p float64; + var w *Var; + + v,ok := symmap[sym]; + if ok { + return v; + } + if f != 0 { + return nil; + } + v = new(Var); + v.name = sym; + symmap[sym] = v; + + p = 1; + for { + p = fmul(p, pname()); + if p == 0 { + break; + } + w = lookup(1); + if w != nil { + v.node = w.node; + v.node.vval = fmul(v.node.vval, p); + break; + } + } + return v; +} + +type Prefix +struct +{ + vval float64; + name string; +} + +var prefix = []Prefix { // prefix table + Prefix { 1e-24, "yocto" }, + Prefix { 1e-21, "zepto" }, + Prefix { 1e-18, "atto" }, + Prefix { 1e-15, "femto" }, + Prefix { 1e-12, "pico" }, + Prefix { 1e-9, "nano" }, + Prefix { 1e-6, "micro" }, + Prefix { 1e-6, "μ" }, + Prefix { 1e-3, "milli" }, + Prefix { 1e-2, "centi" }, + Prefix { 1e-1, "deci" }, + Prefix { 1e1, "deka" }, + Prefix { 1e2, "hecta" }, + Prefix { 1e2, "hecto" }, + Prefix { 1e3, "kilo" }, + Prefix { 1e6, "mega" }, + Prefix { 1e6, "meg" }, + Prefix { 1e9, "giga" }, + Prefix { 1e12, "tera" }, + Prefix { 1e15, "peta" }, + Prefix { 1e18, "exa" }, + Prefix { 1e21, "zetta" }, + Prefix { 1e24, "yotta" } +} + +func +pname() float64 +{ + var i, j, n int; + var s string; + + /* + * rip off normal prefixs + */ + n = len(sym); + for i=0; i 2 && sym[n-1] == 's' { + sym = sym[0:n-1]; + return 1; + } + + return 0; +} + + +// careful multiplication +// exponents (log) are checked before multiply +func +fmul(a, b float64) float64 +{ + var l float64; + + if b <= 0 { + if b == 0 { + return 0; + } + l = math.Log(-b); + } else + l = math.Log(b); + + if a <= 0 { + if a == 0 { + return 0; + } + l += math.Log(-a); + } else + l += math.Log(a); + + if l > Maxe { + Error("overflow in multiply"); + return 1; + } + if l < -Maxe { + Error("underflow in multiply"); + return 0; + } + return a*b; +} + +// careful division +// exponents (log) are checked before divide +func +fdiv(a, b float64) float64 +{ + var l float64; + + if b <= 0 { + if b == 0 { + Error("division by zero: %v %v", a, b); + return 1; + } + l = math.Log(-b); + } else + l = math.Log(b); + + if a <= 0 { + if a == 0 { + return 0; + } + l -= math.Log(-a); + } else + l -= math.Log(a); + + if l < -Maxe { + Error("overflow in divide"); + return 1; + } + if l > Maxe { + Error("underflow in divide"); + return 0; + } + return a/b; +} + +func +fadd(a, b float64) float64 +{ + return a + b; +} -- 2.48.1