From 26b380486dfd2fadf95808c9dcf0f5ff99a11097 Mon Sep 17 00:00:00 2001 From: Carsten Larsen Date: Mon, 27 Feb 2017 23:23:06 +0100 Subject: [PATCH] Prerelease 1.7.0 --- .gitignore | 8 +- HISTORY | 51 +- LICENSE | 74 +- Makefile | 124 ++ Makefile.clang | 451 ------ Makefile.m68k | 451 ------ amath.doxygen | 8 +- amath.vcxproj | 339 ----- amath.vcxproj.filters | 606 -------- app/lib/real.cpp | 530 ------- app/localize/help.h | 87 -- app/localize/ialias.h | 67 - app/localize/ident.h | 86 -- app/localize/lex.h | 130 -- app/localize/start.h | 138 -- app/main/functiondefs.h | 121 -- app/main/functions.cpp | 1213 ---------------- app/main/functions.h | 584 -------- app/main/statements.cpp | 884 ----------- app/main/statements.h | 326 ----- app/system/base/io.cpp | 178 --- app/system/base/io.h | 90 -- app/system/program_test.cpp | 413 ------ build/debian/control-amd64 | 4 +- build/debian/control-i386 | 4 +- build/flexcat/configure | 2 +- builddeb.sh => builddeb | 11 +- builddist | 116 ++ builddist.sh | 118 -- buildwin | 52 + catalog/dansk/amath-help.ct | 32 +- catalog/dansk/amath-keyword.ct | 12 +- catalog/dansk/amath-text.ct | 36 +- catalog/english/amath-help.ct | 4 +- catalog/english/amath-ident.ct | 16 +- catalog/english/amath-text.ct | 2 +- configure | 1145 ++++++++++----- lib/dconv/dmath.cpp | 96 -- lib/dconv/dmath.h | 84 -- lib/dconv/dprint.cpp | 692 --------- lib/dconv/dragon4.cpp | 1161 --------------- lib/dconv/dragon4.h | 134 -- lib/dprint.h | 115 -- lib/dstandard.h | 99 -- scan-build/index.html | 149 -- scan-build/report-020199.html | 477 ------ scan-build/report-262893.html | 1287 ---------------- scan-build/report-273e84.html | 349 ----- scan-build/report-27428e.html | 485 ------- scan-build/report-27e74a.html | 1291 ----------------- scan-build/report-3a56cc.html | 447 ------ scan-build/report-40d42f.html | 781 ---------- scan-build/report-4b20f3.html | 464 ------ scan-build/report-4fd7ba.html | 467 ------ scan-build/report-762445.html | 467 ------ scan-build/report-831a75.html | 469 ------ scan-build/report-a2ee02.html | 1273 ---------------- scan-build/report-b77ae8.html | 1288 ---------------- scan-build/report-cc9ed8.html | 488 ------- scan-build/report-e79f68.html | 349 ----- scan-build/report-e85ac2.html | 313 ---- scan-build/report-f61e62.html | 471 ------ scan-build/report-fcf014.html | 477 ------ scan-build/scanview.css | 62 - scan-build/sorttable.js | 492 ------- lib/platform.h => src/amath.h | 232 +-- lib/clib.h => src/amathc.h | 41 +- lib/mem.h => src/amatht.h | 38 +- src/clib/Makefile | 91 ++ {lib => src}/clib/alloccpy.c | 18 +- {lib => src}/clib/mem.c | 88 +- {lib => src}/clib/memcpy.c | 29 +- {lib => src}/clib/memset.c | 44 +- {lib => src}/clib/strcmp.c | 4 +- {lib => src}/clib/strlen.c | 10 +- {lib => src}/clib/untag.c | 32 +- {lib => src}/complex.h | 21 +- src/cplex/Makefile | 244 ++++ {lib => src}/cplex/cacos.c | 4 +- {lib => src}/cplex/cacosh.c | 4 +- {lib => src}/cplex/cacot.c | 4 +- {lib => src}/cplex/cacoth.c | 4 +- {lib => src}/cplex/cacsc.c | 4 +- {lib => src}/cplex/cacsch.c | 4 +- {lib => src}/cplex/casec.c | 4 +- {lib => src}/cplex/casech.c | 4 +- {lib => src}/cplex/casin.c | 4 +- {lib => src}/cplex/casinh.c | 4 +- {lib => src}/cplex/catan.c | 4 +- {lib => src}/cplex/catanh.c | 4 +- {lib => src}/cplex/ccbrt.c | 4 +- {lib => src}/cplex/ccos.c | 0 {lib => src}/cplex/ccosh.c | 0 {lib => src}/cplex/ccot.c | 4 +- {lib => src}/cplex/ccoth.c | 2 +- {lib => src}/cplex/ccsc.c | 4 +- {lib => src}/cplex/ccsch.c | 2 +- {lib => src}/cplex/cexp.c | 0 {lib => src}/cplex/clog.c | 0 {lib => src}/cplex/clog10.c | 4 +- {lib => src}/cplex/clogb.c | 4 +- {lib => src}/cplex/cpow.c | 0 {lib => src}/cplex/csec.c | 4 +- {lib => src}/cplex/csech.c | 2 +- {lib => src}/cplex/csgn.c | 4 +- {lib => src}/cplex/csin.c | 2 +- {lib => src}/cplex/csinh.c | 0 {lib => src}/cplex/csqrt.c | 0 {lib => src}/cplex/ctan.c | 2 +- {lib => src}/cplex/ctanh.c | 0 {lib => src}/cplex/prim.c | 13 +- {lib => src}/cplex/prim.h | 12 +- src/lib/Makefile | 84 ++ {app => src}/lib/aengine.cpp | 154 +- {app => src}/lib/aengine.h | 50 +- {app => src}/lib/charbuf.cpp | 100 +- {app => src}/lib/charbuf.h | 36 +- {app => src}/lib/charval.h | 13 +- {app => src}/lib/cplex.cpp | 321 +++- {app => src}/lib/cplex.h | 73 +- src/lib/integer.cpp | 809 +++++++++++ src/lib/integer.h | 145 ++ src/lib/nnumb.cpp | 420 ++++++ src/lib/nnumb.h | 146 ++ {app => src}/lib/ntext.cpp | 360 ++--- {app => src}/lib/ntext.h | 61 +- {app => src}/lib/numb.h | 79 +- src/lib/real.cpp | 885 +++++++++++ {app => src}/lib/real.h | 73 +- src/localize/help.h | 90 ++ src/localize/ialias.h | 206 +++ src/localize/ident.h | 82 ++ {app => src}/localize/kword.h | 106 +- src/localize/lex.h | 127 ++ {app => src}/localize/tags.h | 34 +- {app => src}/localize/text.h | 83 +- lib/clib/memoo.cpp => src/main.cpp | 76 +- lib/doc.h => src/main.h | 137 +- src/main/Makefile | 55 + {app => src}/main/evaluator.cpp | 34 +- {app => src}/main/evaluator.h | 36 +- {app/lib => src/main}/fgrid.cpp | 46 +- {app/lib => src/main}/fgrid.h | 32 +- src/main/function/Makefile | 127 ++ src/main/function/absolute.cpp | 46 + src/main/function/absolute.h | 43 + src/main/function/aexcosecant.cpp | 46 + src/main/function/aexcosecant.h | 50 + src/main/function/aexsecant.cpp | 46 + src/main/function/aexsecant.h | 50 + src/main/function/arccos.cpp | 46 + src/main/function/arccos.h | 50 + src/main/function/arccosecant.cpp | 46 + src/main/function/arccosecant.h | 50 + src/main/function/arccotangent.cpp | 46 + src/main/function/arccotangent.h | 50 + src/main/function/arcsecant.cpp | 46 + src/main/function/arcsecant.h | 50 + src/main/function/arcsin.cpp | 46 + src/main/function/arcsin.h | 50 + src/main/function/arctan.cpp | 46 + src/main/function/arctan.h | 50 + src/main/function/ceil.cpp | 46 + src/main/function/ceil.h | 50 + src/main/function/cosecant.cpp | 47 + src/main/function/cosecant.h | 50 + src/main/function/cosine.cpp | 46 + src/main/function/cosine.h | 50 + src/main/function/cotangent.cpp | 46 + src/main/function/cotangent.h | 50 + src/main/function/covercos.cpp | 46 + src/main/function/covercos.h | 50 + src/main/function/coversin.cpp | 46 + src/main/function/coversin.h | 50 + src/main/function/cube.cpp | 46 + src/main/function/cube.h | 50 + src/main/function/defs.h | 138 ++ src/main/function/excosecant.cpp | 47 + src/main/function/excosecant.h | 50 + src/main/function/exsecant.cpp | 46 + src/main/function/exsecant.h | 50 + src/main/function/floor.cpp | 46 + src/main/function/floor.h | 50 + src/main/function/hacovercos.cpp | 46 + src/main/function/hacovercos.h | 50 + src/main/function/hacoversin.cpp | 46 + src/main/function/hacoversin.h | 50 + src/main/function/havercos.cpp | 46 + src/main/function/havercos.h | 50 + src/main/function/haversin.cpp | 46 + src/main/function/haversin.h | 50 + src/main/function/ln.cpp | 46 + src/main/function/ln.h | 50 + src/main/function/log10.cpp | 47 + src/main/function/log10.h | 50 + src/main/function/log2.cpp | 46 + src/main/function/log2.h | 50 + src/main/function/node.cpp | 122 ++ src/main/function/node.h | 71 + src/main/function/round.cpp | 46 + src/main/function/round.h | 52 + src/main/function/secant.cpp | 46 + src/main/function/secant.h | 50 + src/main/function/signum.cpp | 46 + src/main/function/signum.h | 52 + src/main/function/sine.cpp | 46 + src/main/function/sine.h | 50 + src/main/function/square.cpp | 46 + src/main/function/square.h | 50 + src/main/function/tangent.cpp | 46 + src/main/function/tangent.h | 50 + src/main/function/trunc.cpp | 47 + src/main/function/trunc.h | 53 + src/main/function/user.cpp | 74 + src/main/function/user.h | 57 + src/main/function/vercos.cpp | 46 + src/main/function/vercos.h | 50 + src/main/function/versin.cpp | 46 + src/main/function/versin.h | 50 + src/main/functionlist.cpp | 270 ++++ src/main/functionlist.h | 67 + src/main/functions.cpp | 232 +++ src/main/functions.h | 135 ++ {app => src}/main/lexer.cpp | 140 +- {app => src}/main/lexer.h | 36 +- {app => src}/main/nodes.cpp | 144 +- {app => src}/main/nodes.h | 121 +- {app => src}/main/operators.cpp | 301 +++- {app => src}/main/operators.h | 81 +- {app => src}/main/optimizer.cpp | 139 +- {app => src}/main/optimizer.h | 41 +- {app => src}/main/parser.cpp | 455 +++--- {app => src}/main/parser.h | 36 +- src/main/statement/Makefile | 94 ++ src/main/statement/about.cpp | 46 + .../graphlist.h => src/main/statement/about.h | 36 +- src/main/statement/clear.cpp | 46 + src/main/statement/clear.h | 47 + src/main/statement/delete.cpp | 137 ++ src/main/statement/delete.h | 55 + src/main/statement/digits.cpp | 92 ++ src/main/statement/digits.h | 52 + src/main/statement/draw.cpp | 68 + src/main/statement/draw.h | 47 + src/main/statement/empty.cpp | 45 + src/main/statement/empty.h | 50 + src/main/statement/eval.cpp | 107 ++ src/main/statement/eval.h | 55 + src/main/statement/execute.cpp | 67 + src/main/statement/execute.h | 46 + src/main/statement/exit.cpp | 46 + src/main/statement/exit.h | 47 + src/main/statement/funcdef.cpp | 48 + src/main/statement/funcdef.h | 47 + src/main/statement/funclist.cpp | 45 + src/main/statement/funclist.h | 47 + src/main/statement/help.cpp | 73 + src/main/statement/help.h | 54 + src/main/statement/input.cpp | 79 + src/main/statement/input.h | 51 + src/main/statement/license.cpp | 80 + src/main/statement/license.h | 47 + src/main/statement/list.cpp | 67 + src/main/statement/list.h | 47 + src/main/statement/load.cpp | 66 + src/main/statement/load.h | 46 + src/main/statement/memory.cpp | 75 + src/main/statement/memory.h | 47 + src/main/statement/node.cpp | 77 + src/main/statement/node.h | 57 + src/main/statement/output.cpp | 79 + src/main/statement/output.h | 51 + src/main/statement/plot.cpp | 136 ++ src/main/statement/plot.h | 49 + src/main/statement/prefs.cpp | 73 + src/main/statement/prefs.h | 52 + .../main/statement/prompt.cpp | 52 +- src/main/statement/prompt.h | 51 + src/main/statement/save.cpp | 77 + src/main/statement/save.h | 46 + src/main/statement/show.cpp | 57 + src/main/statement/show.h | 46 + src/main/statement/silent.cpp | 88 ++ src/main/statement/silent.h | 58 + src/main/statement/version.cpp | 45 + src/main/statement/version.h | 47 + src/main/statements.h | 59 + {app => src}/main/token.cpp | 33 +- {app => src}/main/token.h | 32 +- src/main/userfunction.cpp | 140 ++ src/main/userfunction.h | 73 + {app => src}/main/values.cpp | 185 ++- {app => src}/main/values.h | 96 +- {app => src}/main/viewer.cpp | 23 +- {app => src}/main/viewer.h | 28 +- {lib => src}/math.h | 38 +- src/real/Makefile | 290 ++++ {lib => src}/real/acos.c | 2 +- {lib => src}/real/acosh.c | 2 +- app/main.cpp => src/real/acvs.c | 19 +- src/real/ahv.c | 38 + src/real/ahvc.c | 37 + {lib => src}/real/asin.c | 2 +- {lib => src}/real/asinh.c | 2 +- {lib => src}/real/atan.c | 2 +- {lib => src}/real/atan2.c | 2 +- {lib => src}/real/atanh.c | 2 +- src/real/aver.c | 38 + {lib => src}/real/cbrt.c | 2 +- {lib => src}/real/ceil.c | 2 +- {lib => src}/real/copysign.c | 2 +- {lib => src}/real/cos.c | 2 +- {lib => src}/real/cosh.c | 2 +- {lib => src}/real/erf.c | 2 +- {lib => src}/real/exp.c | 2 +- {lib => src}/real/expm1.c | 2 +- {lib => src}/real/fabs.c | 2 +- {lib => src}/real/finite.c | 2 +- {lib => src}/real/floor.c | 2 +- {lib => src}/real/fmod.c | 2 +- {lib => src}/real/frexp.c | 2 +- {lib => src}/real/hypot.c | 2 +- {lib => src}/real/isnan.c | 2 +- {lib => src}/real/kcos.c | 2 +- {lib => src}/real/kremp2.c | 2 +- {lib => src}/real/ksin.c | 2 +- {lib => src}/real/kstandard.c | 2 +- {lib => src}/real/ktan.c | 2 +- {lib => src}/real/log.c | 2 +- {lib => src}/real/log10.c | 2 +- {lib => src}/real/log1p.c | 2 +- {lib => src}/real/matherr.c | 2 +- {lib => src}/real/modf.c | 2 +- {lib => src}/real/nextafter.c | 2 +- {lib => src}/real/pow.c | 2 +- {lib => src}/real/prim.h | 11 +- {lib => src}/real/remp2.c | 2 +- {lib => src}/real/rint.c | 2 +- {lib => src}/real/round.c | 2 +- {lib => src}/real/scalbn.c | 2 +- {lib => src}/real/sin.c | 2 +- {lib => src}/real/sinh.c | 2 +- {lib => src}/real/sqrt.c | 2 +- {lib => src}/real/tan.c | 2 +- {lib => src}/real/tanh.c | 2 +- {lib => src}/real/trunc.c | 2 +- src/system/Makefile | 85 ++ {app => src}/system/console.cpp | 10 +- {app => src}/system/console.h | 19 +- {app => src}/system/console_amiga.cpp | 24 +- {app => src}/system/console_amiga.h | 13 +- {app => src}/system/console_stdc.cpp | 36 +- {app => src}/system/console_stdc.h | 30 +- {app => src}/system/filesystem.h | 19 +- {app => src}/system/filesystem_amiga.cpp | 86 +- {app => src}/system/filesystem_amiga.h | 18 +- {app => src}/system/filesystem_stdc.cpp | 45 +- {app => src}/system/filesystem_stdc.h | 23 +- {app => src}/system/graph.cpp | 19 +- {app => src}/system/graph.h | 21 +- {app => src}/system/graph_amiga.cpp | 16 +- {app => src}/system/graph_amiga.h | 12 +- {app => src}/system/graph_gtk.cpp | 2 +- {app => src}/system/graph_gtk.h | 2 +- {app => src}/system/language.cpp | 110 +- {app => src}/system/language.h | 29 +- {app => src}/system/language_amiga.cpp | 6 +- {app => src}/system/language_amiga.h | 25 +- {app => src}/system/language_posix.cpp | 6 +- {app => src}/system/language_posix.h | 5 +- {app => src}/system/language_stdc.cpp | 97 +- {app => src}/system/language_stdc.h | 44 +- {app => src}/system/preferences.cpp | 40 +- {app => src}/system/preferences.h | 24 +- {app => src}/system/preferences_amiga.cpp | 6 +- {app => src}/system/preferences_amiga.h | 11 +- {app => src}/system/preferences_stdc.cpp | 8 +- {app => src}/system/preferences_stdc.h | 17 +- {app => src}/system/proc_amiga.cpp | 11 +- {app => src}/system/proc_amiga.h | 13 +- {app => src}/system/program.cpp | 69 +- {app => src}/system/program.h | 47 +- {app => src}/system/program_amiga.cpp | 14 +- {app => src}/system/program_amiga.h | 14 +- {app => src}/system/program_stdc.cpp | 44 +- {app => src}/system/program_stdc.h | 14 +- src/system/program_test.cpp | 738 ++++++++++ {app => src}/system/program_test.h | 35 +- {app => src}/system/task.h | 23 +- {app => src}/system/task_amiga.cpp | 11 +- {app => src}/system/task_amiga.h | 14 +- {app => src}/system/task_stdc.cpp | 9 +- {app => src}/system/task_stdc.h | 16 +- {app/system/base => src/system}/thread.h | 15 +- {app => src}/system/window_amiga.cpp | 43 +- {app => src}/system/window_amiga.h | 13 +- text/help.cd | 4 +- text/help.sd | 5 +- text/ident.cd | 4 +- text/ident.sd | 5 +- text/keyword.cd | 70 +- text/keyword.sd | 5 +- text/text.cd | 4 +- text/text.sd | 5 +- utext/dk-help.dict | 32 +- utext/dk-keyword.dict | 12 +- utext/dk-text.dict | 36 +- 407 files changed, 17581 insertions(+), 24470 deletions(-) create mode 100644 Makefile delete mode 100644 Makefile.clang delete mode 100644 Makefile.m68k delete mode 100644 amath.vcxproj delete mode 100644 amath.vcxproj.filters delete mode 100644 app/lib/real.cpp delete mode 100644 app/localize/help.h delete mode 100644 app/localize/ialias.h delete mode 100644 app/localize/ident.h delete mode 100644 app/localize/lex.h delete mode 100644 app/localize/start.h delete mode 100644 app/main/functiondefs.h delete mode 100644 app/main/functions.cpp delete mode 100644 app/main/functions.h delete mode 100644 app/main/statements.cpp delete mode 100644 app/main/statements.h delete mode 100644 app/system/base/io.cpp delete mode 100644 app/system/base/io.h delete mode 100644 app/system/program_test.cpp rename builddeb.sh => builddeb (87%) create mode 100755 builddist delete mode 100755 builddist.sh create mode 100755 buildwin delete mode 100644 lib/dconv/dmath.cpp delete mode 100644 lib/dconv/dmath.h delete mode 100644 lib/dconv/dprint.cpp delete mode 100644 lib/dconv/dragon4.cpp delete mode 100644 lib/dconv/dragon4.h delete mode 100644 lib/dprint.h delete mode 100644 lib/dstandard.h delete mode 100644 scan-build/index.html delete mode 100644 scan-build/report-020199.html delete mode 100644 scan-build/report-262893.html delete mode 100644 scan-build/report-273e84.html delete mode 100644 scan-build/report-27428e.html delete mode 100644 scan-build/report-27e74a.html delete mode 100644 scan-build/report-3a56cc.html delete mode 100644 scan-build/report-40d42f.html delete mode 100644 scan-build/report-4b20f3.html delete mode 100644 scan-build/report-4fd7ba.html delete mode 100644 scan-build/report-762445.html delete mode 100644 scan-build/report-831a75.html delete mode 100644 scan-build/report-a2ee02.html delete mode 100644 scan-build/report-b77ae8.html delete mode 100644 scan-build/report-cc9ed8.html delete mode 100644 scan-build/report-e79f68.html delete mode 100644 scan-build/report-e85ac2.html delete mode 100644 scan-build/report-f61e62.html delete mode 100644 scan-build/report-fcf014.html delete mode 100644 scan-build/scanview.css delete mode 100644 scan-build/sorttable.js rename lib/platform.h => src/amath.h (53%) rename lib/clib.h => src/amathc.h (67%) rename lib/mem.h => src/amatht.h (79%) create mode 100644 src/clib/Makefile rename {lib => src}/clib/alloccpy.c (86%) rename {lib => src}/clib/mem.c (77%) rename {lib => src}/clib/memcpy.c (90%) rename {lib => src}/clib/memset.c (85%) rename {lib => src}/clib/strcmp.c (96%) rename {lib => src}/clib/strlen.c (90%) rename {lib => src}/clib/untag.c (82%) rename {lib => src}/complex.h (89%) create mode 100644 src/cplex/Makefile rename {lib => src}/cplex/cacos.c (92%) rename {lib => src}/cplex/cacosh.c (92%) rename {lib => src}/cplex/cacot.c (92%) rename {lib => src}/cplex/cacoth.c (92%) rename {lib => src}/cplex/cacsc.c (92%) rename {lib => src}/cplex/cacsch.c (92%) rename {lib => src}/cplex/casec.c (93%) rename {lib => src}/cplex/casech.c (92%) rename {lib => src}/cplex/casin.c (92%) rename {lib => src}/cplex/casinh.c (92%) rename {lib => src}/cplex/catan.c (92%) rename {lib => src}/cplex/catanh.c (92%) rename {lib => src}/cplex/ccbrt.c (93%) rename {lib => src}/cplex/ccos.c (100%) rename {lib => src}/cplex/ccosh.c (100%) rename {lib => src}/cplex/ccot.c (94%) rename {lib => src}/cplex/ccoth.c (96%) rename {lib => src}/cplex/ccsc.c (94%) rename {lib => src}/cplex/ccsch.c (96%) rename {lib => src}/cplex/cexp.c (100%) rename {lib => src}/cplex/clog.c (100%) rename {lib => src}/cplex/clog10.c (93%) rename {lib => src}/cplex/clogb.c (93%) rename {lib => src}/cplex/cpow.c (100%) rename {lib => src}/cplex/csec.c (94%) rename {lib => src}/cplex/csech.c (96%) rename {lib => src}/cplex/csgn.c (92%) rename {lib => src}/cplex/csin.c (97%) rename {lib => src}/cplex/csinh.c (100%) rename {lib => src}/cplex/csqrt.c (100%) rename {lib => src}/cplex/ctan.c (98%) rename {lib => src}/cplex/ctanh.c (100%) rename {lib => src}/cplex/prim.c (95%) rename {lib => src}/cplex/prim.h (86%) create mode 100644 src/lib/Makefile rename {app => src}/lib/aengine.cpp (76%) rename {app => src}/lib/aengine.h (66%) rename {app => src}/lib/charbuf.cpp (74%) rename {app => src}/lib/charbuf.h (79%) rename {app => src}/lib/charval.h (87%) rename {app => src}/lib/cplex.cpp (52%) rename {app => src}/lib/cplex.h (65%) create mode 100644 src/lib/integer.cpp create mode 100644 src/lib/integer.h create mode 100644 src/lib/nnumb.cpp create mode 100644 src/lib/nnumb.h rename {app => src}/lib/ntext.cpp (56%) rename {app => src}/lib/ntext.h (70%) rename {app => src}/lib/numb.h (65%) create mode 100644 src/lib/real.cpp rename {app => src}/lib/real.h (65%) create mode 100644 src/localize/help.h create mode 100644 src/localize/ialias.h create mode 100644 src/localize/ident.h rename {app => src}/localize/kword.h (51%) create mode 100644 src/localize/lex.h rename {app => src}/localize/tags.h (71%) rename {app => src}/localize/text.h (57%) rename lib/clib/memoo.cpp => src/main.cpp (54%) rename lib/doc.h => src/main.h (78%) create mode 100644 src/main/Makefile rename {app => src}/main/evaluator.cpp (81%) rename {app => src}/main/evaluator.h (78%) rename {app/lib => src/main}/fgrid.cpp (74%) rename {app/lib => src/main}/fgrid.h (76%) create mode 100644 src/main/function/Makefile create mode 100644 src/main/function/absolute.cpp create mode 100644 src/main/function/absolute.h create mode 100644 src/main/function/aexcosecant.cpp create mode 100644 src/main/function/aexcosecant.h create mode 100644 src/main/function/aexsecant.cpp create mode 100644 src/main/function/aexsecant.h create mode 100644 src/main/function/arccos.cpp create mode 100644 src/main/function/arccos.h create mode 100644 src/main/function/arccosecant.cpp create mode 100644 src/main/function/arccosecant.h create mode 100644 src/main/function/arccotangent.cpp create mode 100644 src/main/function/arccotangent.h create mode 100644 src/main/function/arcsecant.cpp create mode 100644 src/main/function/arcsecant.h create mode 100644 src/main/function/arcsin.cpp create mode 100644 src/main/function/arcsin.h create mode 100644 src/main/function/arctan.cpp create mode 100644 src/main/function/arctan.h create mode 100644 src/main/function/ceil.cpp create mode 100644 src/main/function/ceil.h create mode 100644 src/main/function/cosecant.cpp create mode 100644 src/main/function/cosecant.h create mode 100644 src/main/function/cosine.cpp create mode 100644 src/main/function/cosine.h create mode 100644 src/main/function/cotangent.cpp create mode 100644 src/main/function/cotangent.h create mode 100644 src/main/function/covercos.cpp create mode 100644 src/main/function/covercos.h create mode 100644 src/main/function/coversin.cpp create mode 100644 src/main/function/coversin.h create mode 100644 src/main/function/cube.cpp create mode 100644 src/main/function/cube.h create mode 100644 src/main/function/defs.h create mode 100644 src/main/function/excosecant.cpp create mode 100644 src/main/function/excosecant.h create mode 100644 src/main/function/exsecant.cpp create mode 100644 src/main/function/exsecant.h create mode 100644 src/main/function/floor.cpp create mode 100644 src/main/function/floor.h create mode 100644 src/main/function/hacovercos.cpp create mode 100644 src/main/function/hacovercos.h create mode 100644 src/main/function/hacoversin.cpp create mode 100644 src/main/function/hacoversin.h create mode 100644 src/main/function/havercos.cpp create mode 100644 src/main/function/havercos.h create mode 100644 src/main/function/haversin.cpp create mode 100644 src/main/function/haversin.h create mode 100644 src/main/function/ln.cpp create mode 100644 src/main/function/ln.h create mode 100644 src/main/function/log10.cpp create mode 100644 src/main/function/log10.h create mode 100644 src/main/function/log2.cpp create mode 100644 src/main/function/log2.h create mode 100644 src/main/function/node.cpp create mode 100644 src/main/function/node.h create mode 100644 src/main/function/round.cpp create mode 100644 src/main/function/round.h create mode 100644 src/main/function/secant.cpp create mode 100644 src/main/function/secant.h create mode 100644 src/main/function/signum.cpp create mode 100644 src/main/function/signum.h create mode 100644 src/main/function/sine.cpp create mode 100644 src/main/function/sine.h create mode 100644 src/main/function/square.cpp create mode 100644 src/main/function/square.h create mode 100644 src/main/function/tangent.cpp create mode 100644 src/main/function/tangent.h create mode 100644 src/main/function/trunc.cpp create mode 100644 src/main/function/trunc.h create mode 100644 src/main/function/user.cpp create mode 100644 src/main/function/user.h create mode 100644 src/main/function/vercos.cpp create mode 100644 src/main/function/vercos.h create mode 100644 src/main/function/versin.cpp create mode 100644 src/main/function/versin.h create mode 100644 src/main/functionlist.cpp create mode 100644 src/main/functionlist.h create mode 100644 src/main/functions.cpp create mode 100644 src/main/functions.h rename {app => src}/main/lexer.cpp (66%) rename {app => src}/main/lexer.h (74%) rename {app => src}/main/nodes.cpp (72%) rename {app => src}/main/nodes.h (60%) rename {app => src}/main/operators.cpp (64%) rename {app => src}/main/operators.h (69%) rename {app => src}/main/optimizer.cpp (58%) rename {app => src}/main/optimizer.h (69%) rename {app => src}/main/parser.cpp (63%) rename {app => src}/main/parser.h (84%) create mode 100644 src/main/statement/Makefile create mode 100644 src/main/statement/about.cpp rename app/main/graphlist.h => src/main/statement/about.h (77%) create mode 100644 src/main/statement/clear.cpp create mode 100644 src/main/statement/clear.h create mode 100644 src/main/statement/delete.cpp create mode 100644 src/main/statement/delete.h create mode 100644 src/main/statement/digits.cpp create mode 100644 src/main/statement/digits.h create mode 100644 src/main/statement/draw.cpp create mode 100644 src/main/statement/draw.h create mode 100644 src/main/statement/empty.cpp create mode 100644 src/main/statement/empty.h create mode 100644 src/main/statement/eval.cpp create mode 100644 src/main/statement/eval.h create mode 100644 src/main/statement/execute.cpp create mode 100644 src/main/statement/execute.h create mode 100644 src/main/statement/exit.cpp create mode 100644 src/main/statement/exit.h create mode 100644 src/main/statement/funcdef.cpp create mode 100644 src/main/statement/funcdef.h create mode 100644 src/main/statement/funclist.cpp create mode 100644 src/main/statement/funclist.h create mode 100644 src/main/statement/help.cpp create mode 100644 src/main/statement/help.h create mode 100644 src/main/statement/input.cpp create mode 100644 src/main/statement/input.h create mode 100644 src/main/statement/license.cpp create mode 100644 src/main/statement/license.h create mode 100644 src/main/statement/list.cpp create mode 100644 src/main/statement/list.h create mode 100644 src/main/statement/load.cpp create mode 100644 src/main/statement/load.h create mode 100644 src/main/statement/memory.cpp create mode 100644 src/main/statement/memory.h create mode 100644 src/main/statement/node.cpp create mode 100644 src/main/statement/node.h create mode 100644 src/main/statement/output.cpp create mode 100644 src/main/statement/output.h create mode 100644 src/main/statement/plot.cpp create mode 100644 src/main/statement/plot.h create mode 100644 src/main/statement/prefs.cpp create mode 100644 src/main/statement/prefs.h rename app/main/graphlist.cpp => src/main/statement/prompt.cpp (66%) create mode 100644 src/main/statement/prompt.h create mode 100644 src/main/statement/save.cpp create mode 100644 src/main/statement/save.h create mode 100644 src/main/statement/show.cpp create mode 100644 src/main/statement/show.h create mode 100644 src/main/statement/silent.cpp create mode 100644 src/main/statement/silent.h create mode 100644 src/main/statement/version.cpp create mode 100644 src/main/statement/version.h create mode 100644 src/main/statements.h rename {app => src}/main/token.cpp (79%) rename {app => src}/main/token.h (79%) create mode 100644 src/main/userfunction.cpp create mode 100644 src/main/userfunction.h rename {app => src}/main/values.cpp (73%) rename {app => src}/main/values.h (64%) rename {app => src}/main/viewer.cpp (86%) rename {app => src}/main/viewer.h (80%) rename {lib => src}/math.h (72%) create mode 100644 src/real/Makefile rename {lib => src}/real/acos.c (98%) rename {lib => src}/real/acosh.c (98%) rename app/main.cpp => src/real/acvs.c (82%) create mode 100644 src/real/ahv.c create mode 100644 src/real/ahvc.c rename {lib => src}/real/asin.c (98%) rename {lib => src}/real/asinh.c (98%) rename {lib => src}/real/atan.c (98%) rename {lib => src}/real/atan2.c (98%) rename {lib => src}/real/atanh.c (98%) create mode 100644 src/real/aver.c rename {lib => src}/real/cbrt.c (98%) rename {lib => src}/real/ceil.c (98%) rename {lib => src}/real/copysign.c (97%) rename {lib => src}/real/cos.c (98%) rename {lib => src}/real/cosh.c (98%) rename {lib => src}/real/erf.c (99%) rename {lib => src}/real/exp.c (99%) rename {lib => src}/real/expm1.c (99%) rename {lib => src}/real/fabs.c (96%) rename {lib => src}/real/finite.c (97%) rename {lib => src}/real/floor.c (98%) rename {lib => src}/real/fmod.c (98%) rename {lib => src}/real/frexp.c (97%) rename {lib => src}/real/hypot.c (98%) rename {lib => src}/real/isnan.c (96%) rename {lib => src}/real/kcos.c (98%) rename {lib => src}/real/kremp2.c (99%) rename {lib => src}/real/ksin.c (98%) rename {lib => src}/real/kstandard.c (99%) rename {lib => src}/real/ktan.c (99%) rename {lib => src}/real/log.c (98%) rename {lib => src}/real/log10.c (98%) rename {lib => src}/real/log1p.c (99%) rename {lib => src}/real/matherr.c (96%) rename {lib => src}/real/modf.c (98%) rename {lib => src}/real/nextafter.c (98%) rename {lib => src}/real/pow.c (99%) rename {lib => src}/real/prim.h (97%) rename {lib => src}/real/remp2.c (99%) rename {lib => src}/real/rint.c (98%) rename {lib => src}/real/round.c (95%) rename {lib => src}/real/scalbn.c (98%) rename {lib => src}/real/sin.c (98%) rename {lib => src}/real/sinh.c (98%) rename {lib => src}/real/sqrt.c (99%) rename {lib => src}/real/tan.c (98%) rename {lib => src}/real/tanh.c (98%) rename {lib => src}/real/trunc.c (95%) create mode 100644 src/system/Makefile rename {app => src}/system/console.cpp (90%) rename {app => src}/system/console.h (82%) rename {app => src}/system/console_amiga.cpp (81%) rename {app => src}/system/console_amiga.h (88%) rename {app => src}/system/console_stdc.cpp (79%) rename {app => src}/system/console_stdc.h (75%) rename {app => src}/system/filesystem.h (83%) rename {app => src}/system/filesystem_amiga.cpp (72%) rename {app => src}/system/filesystem_amiga.h (81%) rename {app => src}/system/filesystem_stdc.cpp (85%) rename {app => src}/system/filesystem_stdc.h (78%) rename {app => src}/system/graph.cpp (86%) rename {app => src}/system/graph.h (83%) rename {app => src}/system/graph_amiga.cpp (95%) rename {app => src}/system/graph_amiga.h (92%) rename {app => src}/system/graph_gtk.cpp (99%) rename {app => src}/system/graph_gtk.h (96%) rename {app => src}/system/language.cpp (63%) rename {app => src}/system/language.h (78%) rename {app => src}/system/language_amiga.cpp (97%) rename {app => src}/system/language_amiga.h (79%) rename {app => src}/system/language_posix.cpp (96%) rename {app => src}/system/language_posix.h (95%) rename {app => src}/system/language_stdc.cpp (76%) rename {app => src}/system/language_stdc.h (72%) rename {app => src}/system/preferences.cpp (77%) rename {app => src}/system/preferences.h (78%) rename {app => src}/system/preferences_amiga.cpp (94%) rename {app => src}/system/preferences_amiga.h (86%) rename {app => src}/system/preferences_stdc.cpp (95%) rename {app => src}/system/preferences_stdc.h (82%) rename {app => src}/system/proc_amiga.cpp (93%) rename {app => src}/system/proc_amiga.h (91%) rename {app => src}/system/program.cpp (66%) rename {app => src}/system/program.h (73%) rename {app => src}/system/program_amiga.cpp (91%) rename {app => src}/system/program_amiga.h (87%) rename {app => src}/system/program_stdc.cpp (78%) rename {app => src}/system/program_stdc.h (85%) create mode 100644 src/system/program_test.cpp rename {app => src}/system/program_test.h (71%) rename {app => src}/system/task.h (85%) rename {app => src}/system/task_amiga.cpp (93%) rename {app => src}/system/task_amiga.h (90%) rename {app => src}/system/task_stdc.cpp (90%) rename {app => src}/system/task_stdc.h (85%) rename {app/system/base => src/system}/thread.h (91%) rename {app => src}/system/window_amiga.cpp (91%) rename {app => src}/system/window_amiga.h (93%) diff --git a/.gitignore b/.gitignore index 36968d45..4edf3990 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,15 @@ -Makefile +.vs *.kdev4 +*.vcxproj.user +*Debug/* *.o *.obj *.a +*.so amath amath-test catalog/flexcat -*.vcxproj.user -.vs +catalog/flexcat/flexcat *_.3 doxygen.warn *.deb diff --git a/HISTORY b/HISTORY index d48461b7..9192b606 100644 --- a/HISTORY +++ b/HISTORY @@ -2,33 +2,43 @@ --- amath change history --- ------------------------------------------------------------------------------- +v1.7.0 February 28 2017 +- Introduce scientific notation. +- Introduce Not a Number (NaN). +- Fixed bugs related to infinity (Inf). +- Fixed bugs in log of complex numbers. +- Fixed bugs in numeral systems. +- Miscellaneous minor bug fixes. +- Early trigonometric functions. +- Static and dynamic libraries. + v1.6.4 February 04 2017 -- Fixed Windows memory bugs -- Fixed 64 bit memory bugs +- Fixed Windows memory bugs. +- Fixed 64 bit memory bugs. v1.6.3 February 03 2017 -- Improved error handling -- Fixed error in fraction point parsing -- Fixed typo in help text -- 64 bit PowerPC support -- Fixed AROS build errors -- Fixed ARMv6 build errors -- Fixed 64 bit ARM build errors -- Debian support -- NetBSD support +- Improved error handling. +- Fixed error in fraction point parsing. +- Fixed typo in help text. +- 64 bit PowerPC support. +- Fixed AROS build errors. +- Fixed ARMv6 build errors. +- Fixed 64 bit ARM build errors. +- Debian support. +- NetBSD support. v1.6.2 January 24 2017 -- Fixed bug in memory allocation -- Fixed bug in native keybord input -- Included build options in executables -- ARM support +- Fixed bug in memory allocation. +- Fixed bug in native keybord input. +- Included build options in executables. +- ARM support. v1.6.1 January 21 2017 -- Fixed language bug in Windows -- Fixed potential memory bugs -- Clang compiler support -- Update copyright texts -- New doxygen documentation +- Fixed language bug in Windows. +- Fixed potential memory bugs. +- Clang compiler support. +- Update copyright texts. +- New doxygen documentation. v1.6.0 April 7 2016 - Complete internal restructure of source code. @@ -143,4 +153,3 @@ v1.1b July 13 2014 v1.0b July 11 2014 - First public release. - diff --git a/LICENSE b/LICENSE index 3cf14116..d4cf75d5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,8 +1,15 @@ -------------------------------------------------------------------------------- -Copyright (c) 2015-2017 Carsten Sonne Larsen +Copyright (c) 2014-2017 Carsten Sonne Larsen +Copyright (c) 2007 The NetBSD Foundation, Inc. +Copyright (c) 1990, 1993 The Regents of the University of California. All rights reserved. +This code is derived from software written by Stephen L. Moshier. +It is redistributed by the NetBSD Foundation by permission of the author. + +This code is derived from software contributed to Berkeley by +Mike Hibler and Chris Torek. + Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -23,66 +30,3 @@ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -------------------------------------------------------------------------------- - -Copyright (c) 2007 The NetBSD Foundation, Inc. -All rights reserved. - -This code is derived from software written by Stephen L. Moshier. -It is redistributed by the NetBSD Foundation by permission of the author. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS -``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -------------------------------------------------------------------------------- - -Copyright (c) 1990, 1993 -The Regents of the University of California. All rights reserved. - -This code is derived from software contributed to Berkeley by -Mike Hibler and Chris Torek. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -4. Neither the name of the University nor the names of its contributors - may be used to endorse or promote products derived from this software - without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -SUCH DAMAGE. - -------------------------------------------------------------------------------- diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..0e49912b --- /dev/null +++ b/Makefile @@ -0,0 +1,124 @@ + +CC = gcc +CXX = g++ +CFLAGS = -O2 -DWITHTEST -Wall -Isrc -Isrc/main +CXXFLAGS = -O2 -DWITHTEST -Wall -Isrc -Isrc/main +AR = ar +RANLIB = ranlib +LFLAGS = -lappsystem -lfunctions -lstatement -lappmain -lfunctions -lstatement -lappmain -lamathapp -lamathcplex -lamath -lamathc -lstdc++ +LPATH = -Lsrc/lib -Lsrc/clib -Lsrc/real -Lsrc/cplex -Lsrc/main/function -Lsrc/main/statement -Lsrc/main -Lsrc/system +LPATHS = -Lsrc/lib/static -Lsrc/clib/static -Lsrc/real/static -Lsrc/cplex/static -Lsrc/main/function -Lsrc/main/statement -Lsrc/main -Lsrc/system +FLXCAT = build/flexcat/flexcat +MKDIR = mkdir -p +DEL = rm -f +INSTALL = install -m 0755 +PREFIX = /usr + +all: shared-app +app: appmain functions statement appsystem +libs: amathapp amath amathc amathcplex + +amath: static-app +static: static-app + +src/main.o: src/main.cpp + ${CXX} ${CXXFLAGS} -c src/main.cpp -o src/main.o + +appmain: + cd src/main && ${MAKE} + +appsystem: + cd src/system && ${MAKE} + +functions: + cd src/main/function && ${MAKE} + +statement: + cd src/main/statement && ${MAKE} + +amathapp: + cd src/lib && ${MAKE} + +amath: + cd src/real && ${MAKE} + +amathc: + cd src/clib && ${MAKE} + +amathcplex: + cd src/cplex && ${MAKE} + +catalogsa: + ${FLXCAT} text/keyword.cd src/localize/kword.h=text/keyword.sd + ${FLXCAT} text/help.cd src/localize/help.h=text/help.sd + ${FLXCAT} text/ident.cd src/localize/ident.h=text/ident.sd + ${FLXCAT} text/text.cd src/localize/text.h=text/text.sd + +catalogsu: + iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-help.ct >utext/dk-help.dict + iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-ident.ct >utext/dk-ident.dict + iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-text.ct >utext/dk-text.dict + iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-keyword.ct >utext/dk-keyword.dict + +catalogsw: + iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-help.ct >utext/dk-help.dict + iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-ident.ct >utext/dk-ident.dict + iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-text.ct >utext/dk-text.dict + iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-keyword.ct >utext/dk-keyword.dict + +amigacatalogs: + ${MKDIR} dist/catalog/english + ${FLXCAT} text/help.cd catalog/english/amath-help.ct CATALOG dist/catalog/english/amath-help.catalog + ${FLXCAT} text/ident.cd catalog/english/amath-ident.ct CATALOG dist/catalog/english/amath-ident.catalog + ${FLXCAT} text/text.cd catalog/english/amath-text.ct CATALOG dist/catalog/english/amath-text.catalog + ${MKDIR} dist/catalog/dansk + ${FLXCAT} text/help.cd catalog/dansk/amath-help.ct CATALOG dist/catalog/dansk/amath-help.catalog + ${FLXCAT} text/ident.cd catalog/dansk/amath-ident.ct CATALOG dist/catalog/dansk/amath-ident.catalog + ${FLXCAT} text/text.cd catalog/dansk/amath-text.ct CATALOG dist/catalog/dansk/amath-text.catalog + ${FLXCAT} text/keyword.cd catalog/dansk/amath-keyword.ct CATALOG dist/catalog/dansk/amath-keyword.catalog + +shared-app: app libs src/main.o + ${CC} ${CFLAGS} -s src/main.o -o amath ${LPATH} ${LFLAGS} + +static-app: src/main.o + cd src/lib && ${MAKE} static + cd src/clib && ${MAKE} static + cd src/real && ${MAKE} static + cd src/cplex && ${MAKE} static + cd src/main && ${MAKE} static + cd src/system && ${MAKE} static + cd src/main/function && ${MAKE} static + cd src/main/statement && ${MAKE} static + ${CC} ${CFLAGS} -s src/main.o -o amath ${LPATHS} ${LFLAGS} + +.PHONY: test +test: static-app + ./amath test + +.PHONY: install +install: amath + cd src/lib && ${MAKE} install + cd src/clib && ${MAKE} install + cd src/real && ${MAKE} install + cd src/cplex && ${MAKE} install + ${INSTALL} amath ${DESTDIR}${PREFIX}/bin + +.PHONY: uninstall +uninstall: + cd src/lib && ${MAKE} uninstall + cd src/clib && ${MAKE} uninstall + cd src/real && ${MAKE} uninstall + cd src/cplex && ${MAKE} uninstall + ${DEL} ${DESTDIR}${PREFIX}/bin/amath + +clean: + cd src/lib && ${MAKE} clean + cd src/clib && ${MAKE} clean + cd src/real && ${MAKE} clean + cd src/cplex && ${MAKE} clean + cd src/main && ${MAKE} clean + cd src/system && ${MAKE} clean + cd src/main/function && ${MAKE} clean + cd src/main/statement && ${MAKE} clean + ${DEL} src/main.o amath + diff --git a/Makefile.clang b/Makefile.clang deleted file mode 100644 index 8efd537b..00000000 --- a/Makefile.clang +++ /dev/null @@ -1,451 +0,0 @@ - -CC = clang -CXX = clang++ -AR = ar -RANLIB = ranlib -CFLAGS = -DWITHTEST -CXXFLAGS = -DWITHTEST -I. -LFLAGS = -lamathapp -lcomplex -lamath -lcamath -lstdc++ - -FLXCAT = build/flexcat/flexcat -MKDIR = mkdir -p -COPY = cp -DEL = rm -f - -all: libs app - -libs: libamath libcomplex libcamath libamathapp - -evaluator.o: app/main/evaluator.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/evaluator.cpp - -functions.o: app/main/functions.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/functions.cpp - -graphlist.o: app/main/graphlist.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/graphlist.cpp - -lexer.o: app/main/lexer.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/lexer.cpp - -nodes.o: app/main/nodes.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/nodes.cpp - -operators.o: app/main/operators.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/operators.cpp - -optimizer.o: app/main/optimizer.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/optimizer.cpp - -parser.o: app/main/parser.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/parser.cpp - -statements.o: app/main/statements.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/statements.cpp - -token.o: app/main/token.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/token.cpp - -values.o: app/main/values.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/values.cpp - -viewer.o: app/main/viewer.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/viewer.cpp - -console.o: app/system/console.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/console.cpp - -console_amiga.o: app/system/console_amiga.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/console_amiga.cpp - -console_stdc.o: app/system/console_stdc.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/console_stdc.cpp - -filesystem_amiga.o: app/system/filesystem_amiga.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/filesystem_amiga.cpp - -filesystem_stdc.o: app/system/filesystem_stdc.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/filesystem_stdc.cpp - -graph.o: app/system/graph.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/graph.cpp - -graph_amiga.o: app/system/graph_amiga.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/graph_amiga.cpp - -graph_gtk.o: app/system/graph_gtk.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/graph_gtk.cpp - -language.o: app/system/language.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/language.cpp - -language_amiga.o: app/system/language_amiga.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/language_amiga.cpp - -language_posix.o: app/system/language_posix.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/language_posix.cpp - -language_stdc.o: app/system/language_stdc.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/language_stdc.cpp - -preferences.o: app/system/preferences.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/preferences.cpp - -preferences_amiga.o: app/system/preferences_amiga.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/preferences_amiga.cpp - -preferences_stdc.o: app/system/preferences_stdc.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/preferences_stdc.cpp - -proc_amiga.o: app/system/proc_amiga.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/proc_amiga.cpp - -program.o: app/system/program.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/program.cpp - -program_amiga.o: app/system/program_amiga.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/program_amiga.cpp - -program_stdc.o: app/system/program_stdc.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/program_stdc.cpp - -program_test.o: app/system/program_test.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/program_test.cpp - -task_amiga.o: app/system/task_amiga.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/task_amiga.cpp - -task_stdc.o: app/system/task_stdc.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/task_stdc.cpp - -window_amiga.o: app/system/window_amiga.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/window_amiga.cpp - -io.o: app/system/base/io.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/base/io.cpp - -main.o: app/main.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main.cpp - -aengine.o: app/lib/aengine.cpp - ${CC} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/lib/aengine.cpp - -charbuf.o: app/lib/charbuf.cpp - ${CC} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/lib/charbuf.cpp - -cplex.o: app/lib/cplex.cpp - ${CC} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/lib/cplex.cpp - -fgrid.o: app/lib/fgrid.cpp - ${CC} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/lib/fgrid.cpp - -ntext.o: app/lib/ntext.cpp - ${CC} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/lib/ntext.cpp - -real.o: app/lib/real.cpp - ${CC} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/lib/real.cpp - -acos.o: lib/real/acos.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/acos.c - -acosh.o: lib/real/acosh.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/acosh.c - -asin.o: lib/real/asin.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/asin.c - -asinh.o: lib/real/asinh.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/asinh.c - -atan.o: lib/real/atan.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/atan.c - -atan2.o: lib/real/atan2.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/atan2.c - -atanh.o: lib/real/atanh.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/atanh.c - -cbrt.o: lib/real/cbrt.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/cbrt.c - -ceil.o: lib/real/ceil.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/ceil.c - -copysign.o: lib/real/copysign.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/copysign.c - -cos.o: lib/real/cos.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/cos.c - -cosh.o: lib/real/cosh.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/cosh.c - -exp.o: lib/real/exp.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/exp.c - -expm1.o: lib/real/expm1.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/expm1.c - -fabs.o: lib/real/fabs.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/fabs.c - -finite.o: lib/real/finite.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/finite.c - -floor.o: lib/real/floor.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/floor.c - -fmod.o: lib/real/fmod.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/fmod.c - -hypot.o: lib/real/hypot.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/hypot.c - -isnan.o: lib/real/isnan.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/isnan.c - -kcos.o: lib/real/kcos.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/kcos.c - -kremp2.o: lib/real/kremp2.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/kremp2.c - -ksin.o: lib/real/ksin.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/ksin.c - -ktan.o: lib/real/ktan.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/ktan.c - -log.o: lib/real/log.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/log.c - -log10.o: lib/real/log10.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/log10.c - -log1p.o: lib/real/log1p.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/log1p.c - -pow.o: lib/real/pow.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/pow.c - -remp2.o: lib/real/remp2.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/remp2.c - -round.o: lib/real/round.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/round.c - -scalbn.o: lib/real/scalbn.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/scalbn.c - -sin.o: lib/real/sin.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/sin.c - -sinh.o: lib/real/sinh.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/sinh.c - -sqrt.o: lib/real/sqrt.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/sqrt.c - -tan.o: lib/real/tan.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/tan.c - -tanh.o: lib/real/tanh.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/tanh.c - -trunc.o: lib/real/trunc.c - ${CC} -O3 -std=c9x ${CLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/trunc.c - -cacos.o: lib/cplex/cacos.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/cacos.c - -cacosh.o: lib/cplex/cacosh.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/cacosh.c - -cacot.o: lib/cplex/cacot.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/cacot.c - -cacoth.o: lib/cplex/cacoth.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/cacoth.c - -cacsc.o: lib/cplex/cacsc.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/cacsc.c - -cacsch.o: lib/cplex/cacsch.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/cacsch.c - -casec.o: lib/cplex/casec.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/casec.c - -casech.o: lib/cplex/casech.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/casech.c - -casin.o: lib/cplex/casin.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/casin.c - -casinh.o: lib/cplex/casinh.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/casinh.c - -catan.o: lib/cplex/catan.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/catan.c - -catanh.o: lib/cplex/catanh.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/catanh.c - -ccbrt.o: lib/cplex/ccbrt.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/ccbrt.c - -ccos.o: lib/cplex/ccos.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/ccos.c - -ccosh.o: lib/cplex/ccosh.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/ccosh.c - -ccot.o: lib/cplex/ccot.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/ccot.c - -ccoth.o: lib/cplex/ccoth.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/ccoth.c - -ccsc.o: lib/cplex/ccsc.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/ccsc.c - -ccsch.o: lib/cplex/ccsch.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/ccsch.c - -cexp.o: lib/cplex/cexp.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/cexp.c - -clog.o: lib/cplex/clog.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/clog.c - -clog10.o: lib/cplex/clog10.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/clog10.c - -clogb.o: lib/cplex/clogb.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/clogb.c - -cpow.o: lib/cplex/cpow.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/cpow.c - -csec.o: lib/cplex/csec.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/csec.c - -csech.o: lib/cplex/csech.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/csech.c - -csgn.o: lib/cplex/csgn.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/csgn.c - -csin.o: lib/cplex/csin.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/csin.c - -csinh.o: lib/cplex/csinh.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/csinh.c - -csqrt.o: lib/cplex/csqrt.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/csqrt.c - -ctan.o: lib/cplex/ctan.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/ctan.c - -ctanh.o: lib/cplex/ctanh.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/ctanh.c - -prim.o: lib/cplex/prim.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/prim.c - -alloccpy.o: lib/clib/alloccpy.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -c lib/clib/alloccpy.c - -mem.o: lib/clib/mem.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -c lib/clib/mem.c - -memcpy.o: lib/clib/memcpy.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -c lib/clib/memcpy.c - -memset.o: lib/clib/memset.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -c lib/clib/memset.c - -strcmp.o: lib/clib/strcmp.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -c lib/clib/strcmp.c - -strlen.o: lib/clib/strlen.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -c lib/clib/strlen.c - -untag.o: lib/clib/untag.c - ${CC} -O3 -std=c9x ${CFLAGS} -fno-builtin -Wall -Werror -Ilib -c lib/clib/untag.c - -dragon4.o: lib/dconv/dragon4.cpp - ${CXX} -O3 ${CXXFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/dconv -c lib/dconv/dragon4.cpp - -dmath.o: lib/dconv/dmath.cpp - ${CXX} -O3 ${CXXFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/dconv -c lib/dconv/dmath.cpp - -dprint.o: lib/dconv/dprint.cpp - ${CXX} -O3 ${CXXFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/dconv -c lib/dconv/dprint.cpp - -memoo.o: lib/clib/memoo.cpp - ${CXX} -O3 ${CXXFLAGS} -fno-builtin -Wall -Werror -Ilib -Ilib/dconv -c lib/clib/memoo.cpp - -catalogsa: - ${FLXCAT} text/keyword.cd app/localize/kword.h=text/keyword.sd - ${FLXCAT} text/help.cd app/localize/help.h=text/help.sd - ${FLXCAT} text/ident.cd app/localize/ident.h=text/ident.sd - ${FLXCAT} text/text.cd app/localize/text.h=text/text.sd - -catalogsu: - iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-help.ct >utext/dk-help.dict - iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-ident.ct >utext/dk-ident.dict - iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-text.ct >utext/dk-text.dict - iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-keyword.ct >utext/dk-keyword.dict - -catalogsw: - iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-help.ct >utext/dk-help.dict - iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-ident.ct >utext/dk-ident.dict - iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-text.ct >utext/dk-text.dict - iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-keyword.ct >utext/dk-keyword.dict - -libamathapp: aengine.o charbuf.o cplex.o fgrid.o ntext.o real.o - ${AR} rcs libamathapp.a aengine.o charbuf.o cplex.o fgrid.o ntext.o real.o - ${RANLIB} libamathapp.a - -libamath: acos.o acosh.o asin.o asinh.o atan.o atan2.o atanh.o cbrt.o ceil.o copysign.o cos.o cosh.o exp.o expm1.o fabs.o finite.o floor.o fmod.o hypot.o isnan.o kcos.o kremp2.o ksin.o ktan.o log.o log10.o log1p.o pow.o remp2.o round.o scalbn.o sin.o sinh.o sqrt.o tan.o tanh.o trunc.o - ${AR} rcs libamath.a acos.o acosh.o asin.o asinh.o atan.o atan2.o atanh.o cbrt.o ceil.o copysign.o cos.o cosh.o exp.o expm1.o fabs.o finite.o floor.o fmod.o hypot.o isnan.o kcos.o kremp2.o ksin.o ktan.o log.o log10.o log1p.o pow.o remp2.o round.o scalbn.o sin.o sinh.o sqrt.o tan.o tanh.o trunc.o - ${RANLIB} libamath.a - -libcomplex: cacos.o cacosh.o cacot.o cacoth.o cacsc.o cacsch.o casec.o casech.o casin.o casinh.o catan.o catanh.o ccbrt.o ccos.o ccosh.o ccot.o ccoth.o ccsc.o ccsch.o cexp.o clog.o clog10.o clogb.o cpow.o csec.o csech.o csgn.o csin.o csinh.o csqrt.o ctan.o ctanh.o prim.o - ${AR} rcs libcomplex.a cacos.o cacosh.o cacot.o cacoth.o cacsc.o cacsch.o casec.o casech.o casin.o casinh.o catan.o catanh.o ccbrt.o ccos.o ccosh.o ccot.o ccoth.o ccsc.o ccsch.o cexp.o clog.o clog10.o clogb.o cpow.o csec.o csech.o csgn.o csin.o csinh.o csqrt.o ctan.o ctanh.o prim.o - ${RANLIB} libcomplex.a - -libcamath: alloccpy.o mem.o memcpy.o memset.o strcmp.o strlen.o untag.o dragon4.o dmath.o dprint.o memoo.o - ${AR} rcs libcamath.a alloccpy.o mem.o memcpy.o memset.o strcmp.o strlen.o untag.o dragon4.o dmath.o dprint.o memoo.o - ${RANLIB} libcamath.a - -app: libs evaluator.o functions.o graphlist.o lexer.o nodes.o operators.o optimizer.o parser.o statements.o token.o values.o viewer.o console.o console_amiga.o console_stdc.o filesystem_amiga.o filesystem_stdc.o graph.o graph_amiga.o graph_gtk.o language.o language_amiga.o language_posix.o language_stdc.o preferences.o preferences_amiga.o preferences_stdc.o proc_amiga.o program.o program_amiga.o program_stdc.o program_test.o task_amiga.o task_stdc.o window_amiga.o io.o main.o - ${CC} ${CFLAGS} -s -L. -o amath evaluator.o functions.o graphlist.o lexer.o nodes.o operators.o optimizer.o parser.o statements.o token.o values.o viewer.o console.o console_amiga.o console_stdc.o filesystem_amiga.o filesystem_stdc.o graph.o graph_amiga.o graph_gtk.o language.o language_amiga.o language_posix.o language_stdc.o preferences.o preferences_amiga.o preferences_stdc.o proc_amiga.o program.o program_amiga.o program_stdc.o program_test.o task_amiga.o task_stdc.o window_amiga.o io.o main.o ${LFLAGS} - -amigacatalogs: - ${MKDIR} dist/catalog/english - ${FLXCAT} text/help.cd catalog/english/amath-help.ct CATALOG dist/catalog/english/amath-help.catalog - ${FLXCAT} text/ident.cd catalog/english/amath-ident.ct CATALOG dist/catalog/english/amath-ident.catalog - ${FLXCAT} text/text.cd catalog/english/amath-text.ct CATALOG dist/catalog/english/amath-text.catalog - ${MKDIR} dist/catalog/dansk - ${FLXCAT} text/help.cd catalog/dansk/amath-help.ct CATALOG dist/catalog/dansk/amath-help.catalog - ${FLXCAT} text/ident.cd catalog/dansk/amath-ident.ct CATALOG dist/catalog/dansk/amath-ident.catalog - ${FLXCAT} text/text.cd catalog/dansk/amath-text.ct CATALOG dist/catalog/dansk/amath-text.catalog - ${FLXCAT} text/keyword.cd catalog/dansk/amath-keyword.ct CATALOG dist/catalog/dansk/amath-keyword.catalog - -.PHONY: test -test: app - ./amath test - -.PHONY: install -install: app - install -m 0755 amath $(DESTDIR)$(PREFIX)/bin - -clean: - ${DEL} aengine.o charbuf.o cplex.o fgrid.o ntext.o real.o acos.o acosh.o asin.o asinh.o atan.o atan2.o atanh.o cbrt.o ceil.o copysign.o cos.o cosh.o exp.o expm1.o fabs.o finite.o floor.o fmod.o hypot.o isnan.o kcos.o kremp2.o ksin.o ktan.o log.o log10.o log1p.o pow.o remp2.o round.o scalbn.o sin.o sinh.o sqrt.o tan.o tanh.o trunc.o cacos.o cacosh.o cacot.o cacoth.o cacsc.o cacsch.o casec.o casech.o casin.o casinh.o catan.o catanh.o ccbrt.o ccos.o ccosh.o ccot.o ccoth.o ccsc.o ccsch.o cexp.o clog.o clog10.o clogb.o cpow.o csec.o csech.o csgn.o csin.o csinh.o csqrt.o ctan.o ctanh.o prim.o alloccpy.o mem.o memcpy.o memset.o strcmp.o strlen.o untag.o dragon4.o dmath.o dprint.o memoo.o evaluator.o functions.o graphlist.o lexer.o nodes.o operators.o optimizer.o parser.o statements.o token.o values.o viewer.o console.o console_amiga.o console_stdc.o filesystem_amiga.o filesystem_stdc.o graph.o graph_amiga.o graph_gtk.o language.o language_amiga.o language_posix.o language_stdc.o preferences.o preferences_amiga.o preferences_stdc.o proc_amiga.o program.o program_amiga.o program_stdc.o program_test.o task_amiga.o task_stdc.o window_amiga.o io.o main.o libamath.a libcamath.a libcomplex.a libamathapp.a amath - -depend: - @echo Dependencies already done diff --git a/Makefile.m68k b/Makefile.m68k deleted file mode 100644 index 7413a0b2..00000000 --- a/Makefile.m68k +++ /dev/null @@ -1,451 +0,0 @@ - -CC = m68k-amigaos-gcc -CXX = m68k-amigaos-g++ -AR = m68k-amigaos-ar -RANLIB = m68k-amigaos-ranlib -CFLAGS = -m68020 -DWITHTEST -noixemul -CXXFLAGS = -m68020 -DWITHTEST -noixemul -I. -LFLAGS = -lamathapp -lcomplex -lamath -lcamath -lstdc++ - -FLXCAT = build/flexcat/flexcat -MKDIR = mkdir -p -COPY = cp -DEL = rm -f - -all: libs app - -libs: libamath libcomplex libcamath libamathapp - -evaluator.o: app/main/evaluator.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/evaluator.cpp - -functions.o: app/main/functions.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/functions.cpp - -graphlist.o: app/main/graphlist.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/graphlist.cpp - -lexer.o: app/main/lexer.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/lexer.cpp - -nodes.o: app/main/nodes.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/nodes.cpp - -operators.o: app/main/operators.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/operators.cpp - -optimizer.o: app/main/optimizer.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/optimizer.cpp - -parser.o: app/main/parser.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/parser.cpp - -statements.o: app/main/statements.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/statements.cpp - -token.o: app/main/token.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/token.cpp - -values.o: app/main/values.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/values.cpp - -viewer.o: app/main/viewer.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main/viewer.cpp - -console.o: app/system/console.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/console.cpp - -console_amiga.o: app/system/console_amiga.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/console_amiga.cpp - -console_stdc.o: app/system/console_stdc.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/console_stdc.cpp - -filesystem_amiga.o: app/system/filesystem_amiga.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/filesystem_amiga.cpp - -filesystem_stdc.o: app/system/filesystem_stdc.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/filesystem_stdc.cpp - -graph.o: app/system/graph.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/graph.cpp - -graph_amiga.o: app/system/graph_amiga.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/graph_amiga.cpp - -graph_gtk.o: app/system/graph_gtk.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/graph_gtk.cpp - -language.o: app/system/language.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/language.cpp - -language_amiga.o: app/system/language_amiga.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/language_amiga.cpp - -language_posix.o: app/system/language_posix.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/language_posix.cpp - -language_stdc.o: app/system/language_stdc.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/language_stdc.cpp - -preferences.o: app/system/preferences.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/preferences.cpp - -preferences_amiga.o: app/system/preferences_amiga.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/preferences_amiga.cpp - -preferences_stdc.o: app/system/preferences_stdc.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/preferences_stdc.cpp - -proc_amiga.o: app/system/proc_amiga.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/proc_amiga.cpp - -program.o: app/system/program.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/program.cpp - -program_amiga.o: app/system/program_amiga.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/program_amiga.cpp - -program_stdc.o: app/system/program_stdc.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/program_stdc.cpp - -program_test.o: app/system/program_test.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/program_test.cpp - -task_amiga.o: app/system/task_amiga.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/task_amiga.cpp - -task_stdc.o: app/system/task_stdc.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/task_stdc.cpp - -window_amiga.o: app/system/window_amiga.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/window_amiga.cpp - -io.o: app/system/base/io.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/system/base/io.cpp - -main.o: app/main.cpp - ${CXX} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/main.cpp - -aengine.o: app/lib/aengine.cpp - ${CC} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/lib/aengine.cpp - -charbuf.o: app/lib/charbuf.cpp - ${CC} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/lib/charbuf.cpp - -cplex.o: app/lib/cplex.cpp - ${CC} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/lib/cplex.cpp - -fgrid.o: app/lib/fgrid.cpp - ${CC} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/lib/fgrid.cpp - -ntext.o: app/lib/ntext.cpp - ${CC} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/lib/ntext.cpp - -real.o: app/lib/real.cpp - ${CC} -O2 ${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c app/lib/real.cpp - -acos.o: lib/real/acos.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/acos.c - -acosh.o: lib/real/acosh.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/acosh.c - -asin.o: lib/real/asin.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/asin.c - -asinh.o: lib/real/asinh.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/asinh.c - -atan.o: lib/real/atan.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/atan.c - -atan2.o: lib/real/atan2.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/atan2.c - -atanh.o: lib/real/atanh.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/atanh.c - -cbrt.o: lib/real/cbrt.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/cbrt.c - -ceil.o: lib/real/ceil.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/ceil.c - -copysign.o: lib/real/copysign.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/copysign.c - -cos.o: lib/real/cos.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/cos.c - -cosh.o: lib/real/cosh.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/cosh.c - -exp.o: lib/real/exp.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/exp.c - -expm1.o: lib/real/expm1.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/expm1.c - -fabs.o: lib/real/fabs.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/fabs.c - -finite.o: lib/real/finite.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/finite.c - -floor.o: lib/real/floor.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/floor.c - -fmod.o: lib/real/fmod.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/fmod.c - -hypot.o: lib/real/hypot.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/hypot.c - -isnan.o: lib/real/isnan.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/isnan.c - -kcos.o: lib/real/kcos.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/kcos.c - -kremp2.o: lib/real/kremp2.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/kremp2.c - -ksin.o: lib/real/ksin.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/ksin.c - -ktan.o: lib/real/ktan.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/ktan.c - -log.o: lib/real/log.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/log.c - -log10.o: lib/real/log10.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/log10.c - -log1p.o: lib/real/log1p.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/log1p.c - -pow.o: lib/real/pow.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/pow.c - -remp2.o: lib/real/remp2.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/remp2.c - -round.o: lib/real/round.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/round.c - -scalbn.o: lib/real/scalbn.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/scalbn.c - -sin.o: lib/real/sin.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/sin.c - -sinh.o: lib/real/sinh.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/sinh.c - -sqrt.o: lib/real/sqrt.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/sqrt.c - -tan.o: lib/real/tan.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/tan.c - -tanh.o: lib/real/tanh.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/tanh.c - -trunc.o: lib/real/trunc.c - ${CC} -O3 -std=c9x ${CLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/real -c lib/real/trunc.c - -cacos.o: lib/cplex/cacos.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/cacos.c - -cacosh.o: lib/cplex/cacosh.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/cacosh.c - -cacot.o: lib/cplex/cacot.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/cacot.c - -cacoth.o: lib/cplex/cacoth.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/cacoth.c - -cacsc.o: lib/cplex/cacsc.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/cacsc.c - -cacsch.o: lib/cplex/cacsch.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/cacsch.c - -casec.o: lib/cplex/casec.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/casec.c - -casech.o: lib/cplex/casech.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/casech.c - -casin.o: lib/cplex/casin.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/casin.c - -casinh.o: lib/cplex/casinh.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/casinh.c - -catan.o: lib/cplex/catan.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/catan.c - -catanh.o: lib/cplex/catanh.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/catanh.c - -ccbrt.o: lib/cplex/ccbrt.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/ccbrt.c - -ccos.o: lib/cplex/ccos.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/ccos.c - -ccosh.o: lib/cplex/ccosh.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/ccosh.c - -ccot.o: lib/cplex/ccot.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/ccot.c - -ccoth.o: lib/cplex/ccoth.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/ccoth.c - -ccsc.o: lib/cplex/ccsc.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/ccsc.c - -ccsch.o: lib/cplex/ccsch.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/ccsch.c - -cexp.o: lib/cplex/cexp.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/cexp.c - -clog.o: lib/cplex/clog.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/clog.c - -clog10.o: lib/cplex/clog10.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/clog10.c - -clogb.o: lib/cplex/clogb.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/clogb.c - -cpow.o: lib/cplex/cpow.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/cpow.c - -csec.o: lib/cplex/csec.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/csec.c - -csech.o: lib/cplex/csech.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/csech.c - -csgn.o: lib/cplex/csgn.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/csgn.c - -csin.o: lib/cplex/csin.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/csin.c - -csinh.o: lib/cplex/csinh.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/csinh.c - -csqrt.o: lib/cplex/csqrt.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/csqrt.c - -ctan.o: lib/cplex/ctan.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/ctan.c - -ctanh.o: lib/cplex/ctanh.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/ctanh.c - -prim.o: lib/cplex/prim.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c lib/cplex/prim.c - -alloccpy.o: lib/clib/alloccpy.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -c lib/clib/alloccpy.c - -mem.o: lib/clib/mem.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -c lib/clib/mem.c - -memcpy.o: lib/clib/memcpy.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -c lib/clib/memcpy.c - -memset.o: lib/clib/memset.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -c lib/clib/memset.c - -strcmp.o: lib/clib/strcmp.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -c lib/clib/strcmp.c - -strlen.o: lib/clib/strlen.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -c lib/clib/strlen.c - -untag.o: lib/clib/untag.c - ${CC} -O3 -std=c9x ${CFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -c lib/clib/untag.c - -dragon4.o: lib/dconv/dragon4.cpp - ${CXX} -O3 ${CXXFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/dconv -c lib/dconv/dragon4.cpp - -dmath.o: lib/dconv/dmath.cpp - ${CXX} -O3 ${CXXFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/dconv -c lib/dconv/dmath.cpp - -dprint.o: lib/dconv/dprint.cpp - ${CXX} -O3 ${CXXFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/dconv -c lib/dconv/dprint.cpp - -memoo.o: lib/clib/memoo.cpp - ${CXX} -O3 ${CXXFLAGS} -m68020 -fno-builtin -Wall -Werror -Ilib -Ilib/dconv -c lib/clib/memoo.cpp - -catalogsa: - ${FLXCAT} text/keyword.cd app/localize/kword.h=text/keyword.sd - ${FLXCAT} text/help.cd app/localize/help.h=text/help.sd - ${FLXCAT} text/ident.cd app/localize/ident.h=text/ident.sd - ${FLXCAT} text/text.cd app/localize/text.h=text/text.sd - -catalogsu: - iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-help.ct >utext/dk-help.dict - iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-ident.ct >utext/dk-ident.dict - iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-text.ct >utext/dk-text.dict - iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-keyword.ct >utext/dk-keyword.dict - -catalogsw: - iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-help.ct >utext/dk-help.dict - iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-ident.ct >utext/dk-ident.dict - iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-text.ct >utext/dk-text.dict - iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-keyword.ct >utext/dk-keyword.dict - -libamathapp: aengine.o charbuf.o cplex.o fgrid.o ntext.o real.o - ${AR} rcs libamathapp.a aengine.o charbuf.o cplex.o fgrid.o ntext.o real.o - ${RANLIB} libamathapp.a - -libamath: acos.o acosh.o asin.o asinh.o atan.o atan2.o atanh.o cbrt.o ceil.o copysign.o cos.o cosh.o exp.o expm1.o fabs.o finite.o floor.o fmod.o hypot.o isnan.o kcos.o kremp2.o ksin.o ktan.o log.o log10.o log1p.o pow.o remp2.o round.o scalbn.o sin.o sinh.o sqrt.o tan.o tanh.o trunc.o - ${AR} rcs libamath.a acos.o acosh.o asin.o asinh.o atan.o atan2.o atanh.o cbrt.o ceil.o copysign.o cos.o cosh.o exp.o expm1.o fabs.o finite.o floor.o fmod.o hypot.o isnan.o kcos.o kremp2.o ksin.o ktan.o log.o log10.o log1p.o pow.o remp2.o round.o scalbn.o sin.o sinh.o sqrt.o tan.o tanh.o trunc.o - ${RANLIB} libamath.a - -libcomplex: cacos.o cacosh.o cacot.o cacoth.o cacsc.o cacsch.o casec.o casech.o casin.o casinh.o catan.o catanh.o ccbrt.o ccos.o ccosh.o ccot.o ccoth.o ccsc.o ccsch.o cexp.o clog.o clog10.o clogb.o cpow.o csec.o csech.o csgn.o csin.o csinh.o csqrt.o ctan.o ctanh.o prim.o - ${AR} rcs libcomplex.a cacos.o cacosh.o cacot.o cacoth.o cacsc.o cacsch.o casec.o casech.o casin.o casinh.o catan.o catanh.o ccbrt.o ccos.o ccosh.o ccot.o ccoth.o ccsc.o ccsch.o cexp.o clog.o clog10.o clogb.o cpow.o csec.o csech.o csgn.o csin.o csinh.o csqrt.o ctan.o ctanh.o prim.o - ${RANLIB} libcomplex.a - -libcamath: alloccpy.o mem.o memcpy.o memset.o strcmp.o strlen.o untag.o dragon4.o dmath.o dprint.o memoo.o - ${AR} rcs libcamath.a alloccpy.o mem.o memcpy.o memset.o strcmp.o strlen.o untag.o dragon4.o dmath.o dprint.o memoo.o - ${RANLIB} libcamath.a - -app: libs evaluator.o functions.o graphlist.o lexer.o nodes.o operators.o optimizer.o parser.o statements.o token.o values.o viewer.o console.o console_amiga.o console_stdc.o filesystem_amiga.o filesystem_stdc.o graph.o graph_amiga.o graph_gtk.o language.o language_amiga.o language_posix.o language_stdc.o preferences.o preferences_amiga.o preferences_stdc.o proc_amiga.o program.o program_amiga.o program_stdc.o program_test.o task_amiga.o task_stdc.o window_amiga.o io.o main.o - ${CC} ${CFLAGS} -m68020 -noixemul -s -L. -o amath evaluator.o functions.o graphlist.o lexer.o nodes.o operators.o optimizer.o parser.o statements.o token.o values.o viewer.o console.o console_amiga.o console_stdc.o filesystem_amiga.o filesystem_stdc.o graph.o graph_amiga.o graph_gtk.o language.o language_amiga.o language_posix.o language_stdc.o preferences.o preferences_amiga.o preferences_stdc.o proc_amiga.o program.o program_amiga.o program_stdc.o program_test.o task_amiga.o task_stdc.o window_amiga.o io.o main.o ${LFLAGS} - -amigacatalogs: - ${MKDIR} dist/catalog/english - ${FLXCAT} text/help.cd catalog/english/amath-help.ct CATALOG dist/catalog/english/amath-help.catalog - ${FLXCAT} text/ident.cd catalog/english/amath-ident.ct CATALOG dist/catalog/english/amath-ident.catalog - ${FLXCAT} text/text.cd catalog/english/amath-text.ct CATALOG dist/catalog/english/amath-text.catalog - ${MKDIR} dist/catalog/dansk - ${FLXCAT} text/help.cd catalog/dansk/amath-help.ct CATALOG dist/catalog/dansk/amath-help.catalog - ${FLXCAT} text/ident.cd catalog/dansk/amath-ident.ct CATALOG dist/catalog/dansk/amath-ident.catalog - ${FLXCAT} text/text.cd catalog/dansk/amath-text.ct CATALOG dist/catalog/dansk/amath-text.catalog - ${FLXCAT} text/keyword.cd catalog/dansk/amath-keyword.ct CATALOG dist/catalog/dansk/amath-keyword.catalog - -.PHONY: test -test: app - ./amath test - -.PHONY: install -install: app - install -m 0755 amath $(DESTDIR)$(PREFIX)/bin - -clean: - ${DEL} aengine.o charbuf.o cplex.o fgrid.o ntext.o real.o acos.o acosh.o asin.o asinh.o atan.o atan2.o atanh.o cbrt.o ceil.o copysign.o cos.o cosh.o exp.o expm1.o fabs.o finite.o floor.o fmod.o hypot.o isnan.o kcos.o kremp2.o ksin.o ktan.o log.o log10.o log1p.o pow.o remp2.o round.o scalbn.o sin.o sinh.o sqrt.o tan.o tanh.o trunc.o cacos.o cacosh.o cacot.o cacoth.o cacsc.o cacsch.o casec.o casech.o casin.o casinh.o catan.o catanh.o ccbrt.o ccos.o ccosh.o ccot.o ccoth.o ccsc.o ccsch.o cexp.o clog.o clog10.o clogb.o cpow.o csec.o csech.o csgn.o csin.o csinh.o csqrt.o ctan.o ctanh.o prim.o alloccpy.o mem.o memcpy.o memset.o strcmp.o strlen.o untag.o dragon4.o dmath.o dprint.o memoo.o evaluator.o functions.o graphlist.o lexer.o nodes.o operators.o optimizer.o parser.o statements.o token.o values.o viewer.o console.o console_amiga.o console_stdc.o filesystem_amiga.o filesystem_stdc.o graph.o graph_amiga.o graph_gtk.o language.o language_amiga.o language_posix.o language_stdc.o preferences.o preferences_amiga.o preferences_stdc.o proc_amiga.o program.o program_amiga.o program_stdc.o program_test.o task_amiga.o task_stdc.o window_amiga.o io.o main.o libamath.a libcamath.a libcomplex.a libamathapp.a amath - -depend: - @echo Dependencies already done diff --git a/amath.doxygen b/amath.doxygen index faf4b042..9b8d8248 100644 --- a/amath.doxygen +++ b/amath.doxygen @@ -38,7 +38,7 @@ PROJECT_NAME = "amath" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = "1.6.4" +PROJECT_NUMBER = "1.7.0" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a @@ -689,7 +689,7 @@ LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# to be installed. See also https://wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. @@ -1145,7 +1145,7 @@ HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see -# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# https://wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. @@ -1752,7 +1752,7 @@ LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. See -# http://en.wikipedia.org/wiki/BibTeX and \cite for more info. +# https://wikipedia.org/wiki/BibTeX and \cite for more info. # The default value is: plain. # This tag requires that the tag GENERATE_LATEX is set to YES. diff --git a/amath.vcxproj b/amath.vcxproj deleted file mode 100644 index c69a2ab8..00000000 --- a/amath.vcxproj +++ /dev/null @@ -1,339 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {21BD69A9-7F52-48D9-9846-6943E90A87A9} - Win32Proj - amath - 10.0.10240.0 - - - - Application - true - v140 - Unicode - - - Application - true - v140 - Unicode - - - Application - false - v140 - true - Unicode - - - Application - false - v140 - true - Unicode - - - - - - - - - - - - - - - - - - - true - - - true - - - false - - - false - - - - - - Level3 - Disabled - WITHTEST;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - app;lib - - - Console - true - - - - - - - Level3 - Disabled - WITHTEST;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - app;lib - - - Console - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - - - Console - true - true - true - - - - - Level3 - - - MaxSpeed - true - true - WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) - - - Console - true - true - true - - - - - - \ No newline at end of file diff --git a/amath.vcxproj.filters b/amath.vcxproj.filters deleted file mode 100644 index a4946496..00000000 --- a/amath.vcxproj.filters +++ /dev/null @@ -1,606 +0,0 @@ - - - - - {9d6183e0-69ff-4d26-baa1-f350b1e61840} - - - {ed7346f4-5be0-4000-a20a-58ec723ca861} - - - {21ec35c0-8f3a-4f7b-b918-57ae99334945} - - - {43df397b-d8f3-44a8-966d-30f34538b710} - - - {db547663-8a55-4ac5-a59e-1110627b8c0f} - - - {e39a3123-a0a5-469b-a276-941af488213a} - - - {06553b8e-eef4-4337-8018-06693437ad55} - - - {1444b688-d501-412d-b2a0-a641bf6df325} - - - {25a05287-9646-4677-bc30-c25f62848fab} - - - {04260827-107d-42c3-9bf6-e8658eb4cb01} - - - {abdce801-5eed-476b-93aa-8af725658322} - - - - - app - - - app\lib - - - app\lib - - - app\lib - - - app\lib - - - app\lib - - - app\lib - - - app\main - - - app\main - - - app\main - - - app\main - - - app\main - - - app\main - - - app\main - - - app\main - - - app\main - - - app\main - - - app\main - - - app\main - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system\io - - - lib\dconv - - - lib\dconv - - - lib\dconv - - - lib\clib - - - lib\clib - - - lib\clib - - - lib\clib - - - lib\clib - - - lib\clib - - - lib\clib - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\complex - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\real - - - lib\clib - - - - - app\lib - - - app\lib - - - app\lib - - - app\lib - - - app\lib - - - app\lib - - - app\lib - - - app\localize - - - app\localize - - - app\localize - - - app\localize - - - app\localize - - - app\localize - - - app\localize - - - app\localize - - - app\main - - - app\main - - - app\main - - - app\main - - - app\main - - - app\main - - - app\main - - - app\main - - - app\main - - - app\main - - - app\main - - - app\main - - - app\main - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system - - - app\system\io - - - app\system\io - - - lib - - - lib - - - lib - - - lib - - - lib - - - lib - - - lib - - - lib\dconv - - - lib\dconv - - - lib\complex - - - lib\real - - - \ No newline at end of file diff --git a/app/lib/real.cpp b/app/lib/real.cpp deleted file mode 100644 index c0d9d4d1..00000000 --- a/app/lib/real.cpp +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Copyright (c) 2015-2017 Carsten Sonne Larsen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "clib.h" -#include "math.h" -#include "lib/numb.h" -#include "lib/real.h" -#include "lib/cplex.h" - -RealNumber::RealNumber() : - Number(nsysreal) { - x = 0; -} - -RealNumber::RealNumber(double x) : - Number(nsysreal) { - this->x = x; -} - -RealNumber::RealNumber(signed int i) : - Number(nsysreal) { - x = i * 1.0; -} - -RealNumber::RealNumber(unsigned int i) : - Number(nsysreal) { - x = i * 1.0; -} - -RealNumber::~RealNumber() -{ } - -Number* RealNumber::Clone() -{ - return new RealNumber(x); -} - -int RealNumber::GetIntegerValue() -{ - return (int) x; -} - -double RealNumber::GetRealValue() -{ - return x; -} - -void RealNumber::SetRealValue(double value) -{ - x = value; -} - -bool RealNumber::PureComplexValue() -{ - return false; -} - -int RealNumber::GetPrecedence() -{ - return (x < 0.0) ? -1 : 0; -} - -int RealNumber::GetDefaultPrecedence() -{ - return 0; -} - -int RealNumber::IsFinite() -{ - return finite(x); -} - -int RealNumber::IsNaN() -{ - return isnan(x); -} - -Number* RealNumber::Unary() -{ - return new RealNumber(-x); -} - -Number* RealNumber::Add(Number *other) -{ - if (other->system == nsysreal) { - RealNumber *a = (RealNumber*)other; - return new RealNumber(x + a->x); - } else { - return other->Add(this); - } -} - -Number* RealNumber::Sub(Number *other) -{ - if (other->system == nsysreal) { - RealNumber *a = (RealNumber*)other; - return new RealNumber(x - a->x); - } else { - Number *y = other->Unary(); - Number *q = y->Add(this); - delete y; - return q; - } -} - -Number* RealNumber::Mul(Number *other) -{ - if (other->system == nsysreal) { - RealNumber *a = (RealNumber*)other; - return new RealNumber(x * a->x); - } else { - return other->Mul(this); - } -} - -Number* RealNumber::Div(Number *other) -{ - if (other->system == nsysreal) { - RealNumber *a = (RealNumber*)other; - return new RealNumber(x / a->x); - } else { - Number *y = other->Reciprocal(); - Number *q = Mul(y); - delete y; - return q; - } -} - -/** - * @brief Expontation function. - * - * See implementation in pow(double, double) - */ -Number* RealNumber::Raise(Number *exponent) -{ - if (exponent->system == nsysreal) { - return new RealNumber(pow(x, ((RealNumber*)exponent)->x)); - } else { - ComplexNumber *y = new ComplexNumber(x, 0.0); - Number *q = y->Raise(exponent); - delete y; - return q; - } -} - -/** - * @brief Mathematical sign function. - * - * See implementation in sgn(double) - */ -Number* RealNumber::Signum() -{ - return new RealNumber(sgn(x)); -} - -/** - * @brief Mathematical trunc function. - * - * See implementation in trunc(double) - */ -Number* RealNumber::Trunc() -{ - return new RealNumber(trunc(x)); -} - -/** - * @brief Mathematical round function. - * - * See implementation in round(double) - */ -Number* RealNumber::Round() -{ - return new RealNumber(round(x)); -} - -/** - * @brief Mathematical floor function. - * - * See implementation in floor(double) - */ -Number* RealNumber::Floor() -{ - return new RealNumber(floor(x)); -} - -/** - * @brief Mathematical ceiling function. - * - * See implementation in ceil(double) - */ -Number* RealNumber::Ceiling() -{ - return new RealNumber(ceil(x)); -} - -/** - * @brief Absolute value of number. - * - * See implementation in fabs(double) - */ -Number* RealNumber::Absolute() -{ - return new RealNumber(fabs(x)); -} - -/** - * @brief Square root function. - * - * See implementation of square root in sqrt(double) - */ -Number* RealNumber::SquareRoot() -{ - if (x > 0.0) { - return new RealNumber(sqrt(x)); - } - - Number *n = new ComplexNumber(x, 0); - Number *r = n->SquareRoot(); - delete n; - return r; -} - -/** - * @brief Cube root function. - * - * See implementation of cube root in cbrt(double) - */ -Number* RealNumber::CubeRoot() -{ - return new RealNumber(cbrt(x)); -} - -//TODO: Add comment -Number* RealNumber::Reciprocal() -{ - return new RealNumber(1/x); -} - -/** - * @brief Binary logarithm function (base 2). - * - * See implementation of natural logarithm in log(double) - */ -Number* RealNumber::Log2() -{ - return new RealNumber(log(x)/log(2.0)); -} - -/** - * @brief Natural logarithm function (base e). - * - * See implementation of natural logarithm in log(double) - */ -Number* RealNumber::Log() -{ - return new RealNumber(log(x)); -} - -/** - * @brief Base 10 logarithm function. - * - * See implementation of base 10 logarithm in log10(double) - */ -Number* RealNumber::Log10() -{ - return new RealNumber(log10(x)); -} - -/** - * @brief Trigonometric cosine function. - * - * See implementation of cosine function in cos(double) - */ -Number* RealNumber::Cosine() -{ - return new RealNumber(cos(x)); -} - -/** - * @brief Trigonometric secant function. - * - * See implementation of cosine function in cos(double) - */ -Number* RealNumber::Secant() -{ - return new RealNumber(1.0/cos(x)); -} - -/** - * @brief Trigonometric tangent function. - * - * See implementation of tangent function in tan(double) - */ -Number* RealNumber::Tangent() -{ - return new RealNumber(tan(x)); -} - -/** - * @brief Trigonometric cotangent function. - * - * See implementation of tangent function in tan(double) - */ -Number* RealNumber::Cotangent() -{ - return new RealNumber(1.0/tan(x)); -} - -/** - * @brief Hyperbolic sine function. - * - * See implementation of hyperbolic sine function in sinh(double) - */ -Number* RealNumber::HypSine() -{ - return new RealNumber(sinh(x)); -} - -/** - * @brief Hyperbolic cosecant function. - * - * See implementation of hyperbolic sine function in sinh(double) - */ -Number* RealNumber::HypCosecant() -{ - return new RealNumber(1.0/sinh(x)); -} - -/** - * @brief Hyperbolic cosine function. - * - * See implementation of hyperbolic cosine function in cosh(double) - */ -Number* RealNumber::HypCosine() -{ - return new RealNumber(cosh(x)); -} - -/** - * @brief Hyperbolic secant function. - * - * See implementation of hyperbolic cosine function in cosh(double) - */ -Number* RealNumber::HypSecant() -{ - return new RealNumber(1.0/cosh(x)); -} - -/** - * @brief Hyperbolic tangent function. - * - * See implementation of hyperbolic tangent function in tanh(double) - */ -Number* RealNumber::HypTangent() -{ - return new RealNumber(tanh(x)); -} - -/** - * @brief Hyperbolic cotangent function. - * - * See implementation of hyperbolic tangent function in tanh(double) - */ -Number* RealNumber::HypCotangent() -{ - return new RealNumber(1.0/tanh(x)); -} - -/** - * @brief Trigonometric sine function. - * - * See implementation of sine function in sin(double) - */ -Number* RealNumber::Sine() -{ - return new RealNumber(sin(x)); -} - -/** - * @brief Trigonometric cosecant function. - * - * See implementation of sine function in sin(double) - */ -Number* RealNumber::Cosecant() -{ - return new RealNumber(1.0/sin(x)); -} - -/** - * @brief Inverse trigonometric cosine function. - * - * See implementation of inverse trigonometric cosine in acos(double) - */ -Number* RealNumber::ArcCosine() -{ - return new RealNumber(acos(x)); -} - -/** - * @brief Inverse trigonometric secant function. - * - * See implementation of inverse trigonometric cosine in acos(double) - */ -Number* RealNumber::ArcSecant() -{ - return new RealNumber(acos(1.0/x)); -} - -/** - * @brief Inverse trigonometric tangent function. - * - * See implementation of inverse trigonometric tangent in atan(double) - */ -Number* RealNumber::ArcTangent() -{ - return new RealNumber(atan(x)); -} - -/** - * @brief Inverse trigonometric cotangent function. - * - * See implementation of inverse trigonometric tangent in atan(double) - */ -Number* RealNumber::ArcCotangent() -{ - return new RealNumber(atan(1.0/x)); -} - -/** - * @brief Inverse trigonometric sine function. - * - * See implementation of inverse trigonometric sine in asin(double) - */ -Number* RealNumber::ArcSine() -{ - return new RealNumber(asin(x)); -} - -/** - * @brief Inverse trigonometric cosecant function. - * - * See implementation of inverse trigonometric sine in asin(double) - */ -Number* RealNumber::ArcCosecant() -{ - return new RealNumber(asin(1.0/x)); -} - -/** - * @brief Inverse hyperbolic cosine function. - * - * See implementation of inverse hyperbolic cosine in acosh(double) - */ -Number* RealNumber::HypArcCosine() -{ - return new RealNumber(acosh(x)); -} - -/** - * @brief Inverse hyperbolic secant function. - * - * See implementation of inverse hyperbolic cosine in acosh(double) - */ -Number* RealNumber::HypArcSecant() -{ - return new RealNumber(acosh(1.0/x)); -} - -/** - * @brief Inverse hyperbolic sine function. - * - * See implementation of inverse hyperbolic sine in asinh(double) - */ -Number* RealNumber::HypArcSine() -{ - return new RealNumber(asinh(x)); -} - -/** - * @brief Inverse hyperbolic cosecant function. - * - * See implementation of inverse hyperbolic sine in asinh(double) - */ -Number* RealNumber::HypArcCosecant() -{ - return new RealNumber(asinh(1.0/x)); -} - -/** - * @brief Inverse hyperbolic tangent function. - * - * See implementation hyperbolic tangent in atanh(double) - */ -Number* RealNumber::HypArcTangent() -{ - return new RealNumber(atanh(x)); -} - -/** - * @brief Inverse hyperbolic cotangent function. - * - * See implementation hyperbolic tangent in atanh(double) - */ -Number* RealNumber::HypArcCotangent() -{ - return new RealNumber(atanh(1.0/x)); -} diff --git a/app/localize/help.h b/app/localize/help.h deleted file mode 100644 index dcbd7e06..00000000 --- a/app/localize/help.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2015-2017 Carsten Sonne Larsen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Generated with FlexCat. For more information, see: - * http://sourceforge.net/projects/flexcat/ - * - */ - -#ifndef AMATH_LOCALIZE_HELP_H -#define AMATH_LOCALIZE_HELP_H - -/** - * @file help.h - * @brief Help texts for statement. - * - */ - -#include "clib.h" -#include "localize/lex.h" - -#define symzero Symbol(0) - -struct helptextdef { - int id; - Symbol symbol; - const char *text; -}; - -static const helptextdef helptexts[] = { - { 0, symzero, "Enter command or expression to evaluate.#NEWLINE##SYNTAXHIGHLIGHT#Example: 2+3-cos(3)#NORMALTEXT##NEWLINE# #NEWLINE#More help is available for designated topics.#NEWLINE#-------------------------------------------------#NEWLINE#functions Base functions.#NEWLINE#trigon Trigonometric functions.#NEWLINE#hyper Hyperbolic functions.#NEWLINE#complex Syntax for complex numbers.#NEWLINE#statements Available statements.#NEWLINE#operators Supported operators.#NEWLINE#-------------------------------------------------#NEWLINE##SYNTAXHIGHLIGHT#Example: help trigon#NEWLINE#" }, - { 1, symoperator, "-------------------------------------------------#NEWLINE# + Mathematical addition.#NEWLINE# - Mathematical subtraction.#NEWLINE# * Mathematical multiplication.#NEWLINE# / Mathematical division.#NEWLINE# ^ Mathematical exponentiation.#NEWLINE# = Assignment of variable values.#NEWLINE# | Absolute value of number. #NEWLINE#-------------------------------------------------#NEWLINE#" }, - { 2, symfunction, "-------------------------------------------------#NEWLINE#abs Absolute value of number.#NEWLINE#sgn Mathematical signum function.#NEWLINE#round Round to nearest integer number.#NEWLINE#trunc Discard fraction part of number.#NEWLINE#floor Mathematical floor function.#NEWLINE#ceil Mathematical ceiling function.#NEWLINE#sqrt Square root function (exp 1/2).#NEWLINE#cbrt Cube root function (exp 1/3).#NEWLINE#lb Binary logarithm function (base 2).#NEWLINE#ln Natural logarithm function (base e).#NEWLINE#lg Common logarithm function (base 10).#NEWLINE#-------------------------------------------------#NEWLINE##SYNTAXHIGHLIGHT#Example: round(1.55)#NORMALTEXT##NEWLINE#" }, - { 3, symtrigon, "-------------------------------------------------#NEWLINE#sin Trigonometric sine function.#NEWLINE#cos Trigonometric cosine function.#NEWLINE#tan Trigonometric tangent function.#NEWLINE#cot Trigonometric cotangent function.#NEWLINE#sec Trigonometric secant function.#NEWLINE#csc Trigonometric cosecant function.#NEWLINE#asin Inverse trigonometric sine function.#NEWLINE#acos Inverse trigonometric cosine function.#NEWLINE#atan Inverse trigonometric tangent function.#NEWLINE#acot Inverse trigonometric cotangent function.#NEWLINE#asec Inverse trigonometric secant function.#NEWLINE#acsc Inverse trigonometric cosecant function.#NEWLINE#-------------------------------------------------#NEWLINE#Inverse functions can be prefixed with ar or arc #NEWLINE#instead of a.#NEWLINE#" }, - { 4, symhyper, "-------------------------------------------------#NEWLINE#sinh Hyperbolic sine function.#NEWLINE#cosh Hyperbolic cosine function.#NEWLINE#tanh Hyperbolic tangent function.#NEWLINE#coth Hyperbolic cotangent function.#NEWLINE#sech Hyperbolic secant function.#NEWLINE#csch Hyperbolic cosecant function. #NEWLINE#asinh Inverse hyperbolic sine function.#NEWLINE#acosh Inverse hyperbolic cosine function.#NEWLINE#atanh Inverse hyperbolic tangent function.#NEWLINE#acoth Inverse hyperbolic cotangent function.#NEWLINE#asech Inverse hyperbolic secant function.#NEWLINE#acsch Inverse hyperbolic cosecant function.#NEWLINE#-------------------------------------------------#NEWLINE#Inverse functions can be prefixed with ar or arc #NEWLINE#instead of a.#NEWLINE#" }, - { 5, symstatement, "---------------------------------------------------------#NEWLINE#clear Clear console window.#NEWLINE#def Define function.#NEWLINE#delete Delete variable or function.#NEWLINE#digits Set number of significant digits.#NEWLINE#eval Evaluate arithmetic expression.#NEWLINE#execute Execute statements in a file.#NEWLINE#functions Show list of user defined functions.#NEWLINE#input Change numeral input system (experimental).#NEWLINE#help Show basic help text.#NEWLINE#output Change numeral output system (experimental).#NEWLINE#list Show content of a directory.#NEWLINE#show Show content of a file.#NEWLINE#load Load variable and functions from file.#NEWLINE#save Save variable and functions to file.#NEWLINE#variables Show list of variables.#NEWLINE#version Show version string.#NEWLINE#memory Show internal memory usage.#NEWLINE#exit Exit program.#NEWLINE#---------------------------------------------------------#NEWLINE#The def and eval statements are optional. Functions and#NEWLINE#variables statements can be shorten to funcs and vars.#NEWLINE#" }, - { 6, symcomplex, "Expressions with complex numbers are written using an i to denote#NEWLINE#the imaginary value. Complex numbers can seamlessly be mixed with#NEWLINE#real numbers.#NEWLINE##SYNTAXHIGHLIGHT#Syntax: 2+3i#NEWLINE#Example: 2+3.2i*cos(-1i)+5/7#NEWLINE#" }, - { 7, symclear, "The clear statement erases all text in the console window.#NEWLINE##SYNTAXHIGHLIGHT#Syntax: clear#NEWLINE#" }, - { 8, symdef, "The def statement is used to define functions. When defining a function#NEWLINE#it is possible to omit the def keyword. Defined functions can be shown#NEWLINE#using the functions statement.#NEWLINE##SYNTAXHIGHLIGHT#Syntax: def f(x)=2*x+3#NEWLINE#Optional syntax: f(x)=2*x+3#NEWLINE#" }, - { 9, symdelete, "The delete statement can delete variable and functions. To delete a#NEWLINE#single variable or functions use the name of the function or variable.#NEWLINE#To delete all functions or variables specify either the variable or#NEWLINE#function keyword.#NEWLINE##SYNTAXHIGHLIGHT#Syntax: delete f(x)#NEWLINE#Syntax: delete variables#NEWLINE#" }, - { 10, symdigits, "The digits statement defines the displayed number of significant digits.#NEWLINE#To show current configuration use the digits statement without specifying#NEWLINE#the number.#NEWLINE# #SYNTAXHIGHLIGHT#Syntax: digits 7#NEWLINE#" }, - { 11, symeval, "The eval statement evaluates an expression. When evaluating an expression#NEWLINE#it is possible to omit the eval keyword.#NEWLINE##SYNTAXHIGHLIGHT#Syntax: eval 2.4*x+3.2#NEWLINE#Optional syntax: 2.4*x+3.2#NEWLINE#" }, - { 12, symexecute, "The execute statement reads the content of a file and execute all statements.#NEWLINE##SYNTAXHIGHLIGHT#Syntax: execute \"savedfile\"#NEWLINE#" }, - { 13, syminput, "The input statement either changes or shows the how numeral input is interpreted.#NEWLINE#Possible input systems are: binary, octal, decimal and hexadecimal. Default is#NEWLINE#decimal. To use positional systems with other bases specify the base number.#NEWLINE#Numeral output system can be modified using the output statement.#NEWLINE##SYNTAXHIGHLIGHT#Syntax: input hexadecimal#NEWLINE#Syntax: input 4#NEWLINE#" }, - { 14, symhelp, "The help statement can be used to display help about topics and statements.#NEWLINE##SYNTAXHIGHLIGHT#Syntax: help variables#NEWLINE#" }, - { 15, symoutput, "The output statement either changes or shows the how numeral output is shown.#NEWLINE#Possible output systems are: binary, octal, decimal and hexadecimal. Default#NEWLINE#is decimal. To use positional systems with other bases specify the base number.#NEWLINE#Numeral input system can be modified using the input statement.#NEWLINE##SYNTAXHIGHLIGHT#Syntax: output octal#NEWLINE#" }, - { 16, symlist, "No description is available for the list statement.#NEWLINE#" }, - { 17, symshow, "The show statement displays the content of a file.#NEWLINE##SYNTAXHIGHLIGHT#Syntax: show \"filetosee\"#NEWLINE#" }, - { 18, symload, "The load statement retrieves a set of defined variables and functions from#NEWLINE#a file. Variables and functions can be saved using the save statement.#NEWLINE##SYNTAXHIGHLIGHT#Syntax: load \"savedwork\"#NEWLINE#" }, - { 19, symsave, "The save statement saves defined variables and functions to a file in a#NEWLINE#plain text format. Saved variables and functions can be retrieved using#NEWLINE#the load statement.#NEWLINE# #SYNTAXHIGHLIGHT#Syntax: save \"worktokeep\"#NEWLINE#" }, - { 20, symversion, "Show which version of amath is running.#NEWLINE#" }, - { 21, symmem, "Show internal memory usage together with maximum usage.#NEWLINE#" }, - { 22, symprefs, "There is no help for prefs statement now.#NEWLINE#" }, - { 23, symvariable, "The variable statement shows a list of variables in memory.#NEWLINE##SYNTAXHIGHLIGHT#Syntax: variables#NEWLINE##NORMALTEXT#optional syntax: vars#NEWLINE#" }, - { 24, symexit, "The exit statement shuts down amath.#NEWLINE##SYNTAXHIGHLIGHT#Syntax: exit#NEWLINE#" }, - { 25, syme, "Euler's number is base of the exponential function which equals its own#NEWLINE#derivative. It is approximately equal to 2.71828.#NEWLINE##SYNTAXHIGHLIGHT#Example: ln(e)#NEWLINE#" }, - { 26, sympi, "Pi is the ratio of the circumference of a circle to its diameter. Being an#NEWLINE#irrational number, pi cannot be expressed exactly as a common fraction.#NEWLINE#The value of pi is commonly approximated as #SYNTAXHIGHLIGHT#3.14159#NORMALTEXT#.#NEWLINE#" }, - { 27, symi, "The imaginary unit is denoted and commonly referred to as i.#NEWLINE#The imaginary unit is a number, which when multiplied#NEWLINE#by itself gives -1.#NEWLINE#" }, - { 28, symins, "No help is available for the ins variable#NEWLINE#" }, - { 29, symbin, "No help is available for the binary keyword#NEWLINE" }, - { 30, symoct, "No help is available for the octal keyword#NEWLINE" }, - { 31, symdec, "No help is available for the decimal keyword#NEWLINE" }, - { 32, symhex, "No help is available for the hexadecimal keyword#NEWLINE" }, - { -1, symzero, EMPTYSTRING } -}; - -#endif diff --git a/app/localize/ialias.h b/app/localize/ialias.h deleted file mode 100644 index a79e8adc..00000000 --- a/app/localize/ialias.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2015-2017 Carsten Sonne Larsen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef AMATH_LOCALIZE_IDENT_ALIAS_H -#define AMATH_LOCALIZE_IDENT_ALIAS_H - -struct identalias { - const char *ident; - const char *alias; -}; - -static const identalias identaliases[] = { - { "sqrt", "sqr" }, - { "cbrt", "cbr" }, - { "log2", "lb" }, - { "log", "lg" }, - { "log10", "lg" }, - { "arsin", "asin" }, - { "arcos", "acos" }, - { "artan", "atan" }, - { "arcot", "acot" }, - { "arsec", "asec" }, - { "arcsc", "acsc" }, - { "arcsin", "asin" }, - { "arccos", "acos" }, - { "arctan", "atan" }, - { "arccot", "acot" }, - { "arcsec", "asec" }, - { "arccsc", "acsc" }, - { "arsinh", "asinh" }, - { "arcosh", "acosh" }, - { "artanh", "atanh" }, - { "arcoth", "acoth" }, - { "arsech", "asech" }, - { "arcsch", "acsch" }, - { "arcsinh", "asinh" }, - { "arccosh", "acosh" }, - { "arctanh", "atanh" }, - { "arccoth", "acoth" }, - { "arcsech", "asech" }, - { "arccsch", "acsch" } -}; - -#endif diff --git a/app/localize/ident.h b/app/localize/ident.h deleted file mode 100644 index 2d245a93..00000000 --- a/app/localize/ident.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2015-2017 Carsten Sonne Larsen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Generated with FlexCat. For more information, see: - * http://sourceforge.net/projects/flexcat/ - * - */ - -#ifndef AMATH_LOCALIZE_IDENT_H -#define AMATH_LOCALIZE_IDENT_H - -/** - * @file ident.h - * @brief Help texts for built-in functions. - * - */ - -#include "clib.h" - -struct identhelpdef { - int id; - const char *ident; - const char *text; -}; - -static const identhelpdef identtexts[] = { - { 0, "abs", "No help is available for this function.#NEWLINE#" }, - { 1, "sgn", "No help is available for this function.#NEWLINE#" }, - { 2, "round", "No help is available for this function.#NEWLINE#" }, - { 3, "trunc", "No help is available for this function.#NEWLINE#" }, - { 4, "floor", "No help is available for this function.#NEWLINE#" }, - { 5, "ceil", "No help is available for this function.#NEWLINE#" }, - { 6, "sqr", "No help is available for this function.#NEWLINE#" }, - { 7, "cbr", "No help is available for this function.#NEWLINE#" }, - { 8, "lb", "No help is available for this function.#NEWLINE#" }, - { 9, "ln", "No help is available for this function.#NEWLINE#" }, - { 10, "lg", "No help is available for this function.#NEWLINE#" }, - { 11, "sin", "No help is available for this function.#NEWLINE#" }, - { 12, "cos", "No help is available for this function.#NEWLINE#" }, - { 13, "tan", "No help is available for this function.#NEWLINE#" }, - { 14, "cot", "No help is available for this function.#NEWLINE#" }, - { 15, "sec", "No help is available for this function.#NEWLINE#" }, - { 16, "csc", "No help is available for this function.#NEWLINE#" }, - { 17, "asin", "No help is available for this function.#NEWLINE#" }, - { 18, "acos", "No help is available for this function.#NEWLINE#" }, - { 19, "atan", "No help is available for this function.#NEWLINE#" }, - { 20, "acot", "No help is available for this function.#NEWLINE#" }, - { 21, "asec", "No help is available for this function.#NEWLINE#" }, - { 22, "acsc", "No help is available for this function.#NEWLINE#" }, - { 23, "sinh", "No help is available for this function.#NEWLINE#" }, - { 24, "cosh", "No help is available for this function.#NEWLINE#" }, - { 25, "tanh", "No help is available for this function.#NEWLINE#" }, - { 26, "coth", "No help is available for this function.#NEWLINE#" }, - { 27, "sech", "No help is available for this function.#NEWLINE#" }, - { 28, "csch", "No help is available for this function.#NEWLINE#" }, - { 29, "asinh", "No help is available for this function.#NEWLINE#" }, - { 30, "acosh", "No help is available for this function.#NEWLINE#" }, - { 31, "atanh", "No help is available for this function.#NEWLINE#" }, - { 32, "acoth", "No help is available for this function.#NEWLINE#" }, - { 33, "asech", "No help is available for this function.#NEWLINE#" }, - { 34, "acsch", "No help is available for this function.#NEWLINE#" }, - { -1, EMPTYSTRING, EMPTYSTRING } -}; - -#endif diff --git a/app/localize/lex.h b/app/localize/lex.h deleted file mode 100644 index 8903dc39..00000000 --- a/app/localize/lex.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (c) 2015-2017 Carsten Sonne Larsen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef AMATH_TEXT_LEX_H -#define AMATH_TEXT_LEX_H - -/** - * @file lex.h - * @brief Lexer defitions used by other classes. - * - */ - -/** - * @brief Symbols generated by the Lexer. - * - */ -typedef enum { - symunknown, symident, symqident, symnumber, - symplus, symminus, symtimes, symslash, sympower, - symabsolute, symassign, symlparen, symrparen, - symfuncsqrt, symfunccbrt, symfunclog, symfuncln, - symhelp, symeval, symdelete, symall, symclear, symdef, symexit, - symoperator, symstatement, symfunction, symvariable, - symtrigon, symhyper, symcomplex, - syme, sympi, symi,symins, symdelimiter, symend, - symshow, symlist, symload, symsave, symexecute, - syminput, symoutput, symdigits, - symdec, symhex, symbin, symoct, - symmem, symprefs, symprompt, symversion, - symplot, symdraw -} Symbol; - -/** - * @brief Character representation of operator tied with its symbol. - * - */ -struct operatordef { - char chr; - Symbol symbol; -}; - -static const operatordef operators[] = { - { '+', symplus}, - { '-', symminus}, - { '/', symslash}, - { '*', symtimes}, - { '^', sympower}, - { '(', symlparen}, - { ')', symrparen}, - { '|', symabsolute}, - { '=', symassign}, - { '\n', symdelimiter}, - { ';', symdelimiter} -}; - -/* -static const keyworddef keywords[] = { - { "clear", symclear}, - { "def", symdef}, - { "delete", symdelete}, - { "e", syme}, - { "i", symi}, - { "pi", sympi}, - { "ins", symins}, - { "eval", symeval}, - { "complex", symcomplex}, - { "execute", symexecute}, - { "exit", symexit}, - { "funcs", symfunction}, - { "functions", symfunction}, - { "trigon", symtrigon}, - { "trigonometric", symtrigon}, - { "hyper", symhyper}, - { "hyperbolic", symhyper}, - { "help", symhelp}, - { "list", symlist}, - { "load", symload}, - { "operators", symoperator}, - { "quit", symexit}, - { "save", symsave}, - { "show", symshow}, - { "statements", symstatement}, - { "vars", symvariable}, - { "variables", symvariable}, - { "version", symversion}, - { "digits", symdigits}, - { "mem", symmem}, - { "memory", symmem}, - { "prefs", symprefs}, - { "preferences", symprefs}, - { "prompt", symprompt}, - { "input", syminput}, - { "output", symoutput}, - { "bin", symbin}, - { "binary", symbin}, - { "oct", symoct}, - { "octal", symoct}, - { "dec", symdec}, - { "decimal", symdec}, - { "hex", symhex}, - { "hexadecimal", symhex}, - { "draw", symdraw}, - { "plot", symplot} -}; -*/ - -#endif diff --git a/app/localize/start.h b/app/localize/start.h deleted file mode 100644 index 2be6e2d4..00000000 --- a/app/localize/start.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2015-2017 Carsten Sonne Larsen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef AMATH_TEXT_START_H -#define AMATH_TEXT_START_H -/******************************************************************************/ -/** - * @file start.h - * @brief Start message and version text - * - */ -/******************************************************************************/ -#include "clib.h" -/******************************************************************************/ -#if defined(INTELCPU) || defined(i386) || defined(i486) || \ - defined(intel) || defined(x86) || defined(i86pc) || \ - defined(__i386__) || defined(_M_IX86) -# ifdef TXTCPU -# undef TXTCPU -# endif -# define TXTCPU "i386" -#endif -#if defined(__x86_64__) || defined(_M_AMD64) -# define TXTCPU "amd64" -#endif -/******************************************************************************/ -#if defined(__powerpc__) || defined(__powerpc64__) -# define TXTCPU "PowerPC" -#endif -/******************************************************************************/ -#if defined(__arm__) || defined(_M_ARM) || defined(__ARM_ARCH_6__) -# define TXTCPU "arm" -#endif -#if defined(__aarch64__) || defined(_M_ARM64) -# define TXTCPU "arm64" -#endif -/******************************************************************************/ -#ifdef mc68000 -# define TXTCPU "68000+" -#endif -/******************************************************************************/ -#ifdef mc68020 -# ifdef TXTCPU -# undef TXTCPU -# endif -# define TXTCPU "68020" -#endif -/******************************************************************************/ -#ifdef mc68030 -# ifdef TXTCPU -# undef TXTCPU -# endif -# define TXTCPU "68030" -#endif -/******************************************************************************/ -#ifdef mc68040 -# ifdef TXTCPU -# undef TXTCPU -# endif -# define TXTCPU "68040" -#endif -/******************************************************************************/ -#ifdef mc68060 -# ifdef TXTCPU -# undef TXTCPU -# endif -# define TXTCPU "68060" -#endif -/******************************************************************************/ -#ifndef TXTCPU -//#error what cpu is this ?! -# define TXTCPU EMPTYSTRING -#endif -/******************************************************************************/ -#if defined(TXTCPU) && defined(__HAVE_68881__) -# define TXTFPU SPACE "FPU" -#else -# define TXTFPU EMPTYSTRING -#endif -/******************************************************************************/ -#if defined(WITHTEST) && !defined(ANSICONSOLE) -# define TXTOPTS "TEST" -#endif -#if !defined(WITHTEST) && defined(ANSICONSOLE) -# define TXTOPTS "ANSI" -#endif -#if defined(WITHTEST) && defined(ANSICONSOLE) -# define TXTOPTS "ANSI, TEST" -#endif -#ifdef TXTOPTS -# define TXTOPTMSG SPACE "(OPT: " TXTOPTS ")" -#else -# define TXTOPTMSG EMPTYSTRING -#endif -/******************************************************************************/ -#define TXTARCH TXTCPU TXTFPU -#define RELDATESTAMP "(04-02-2017)" -#define TXTDOSVERSION "\0$VER: amath 1.64" SPACE RELDATESTAMP SPACE TXTARCH -#define TXTTITLE "amath version 1.6.4" -#define TXTCOPYRIGHT "(c) 2017 Carsten Sonne Larsen" -#define TXTSTARTMSG TXTTITLE SPACE TXTCOPYRIGHT -/******************************************************************************/ -#define TXTVERSMSG TXTTITLE SPACE RELDATESTAMP SPACE TXTARCH -#define TXTCOMPMSG "Compiled with " COMP_NAME SPACE COMP_VERS TXTOPTMSG -/******************************************************************************/ -#define TXTEXTCOPYRIGHT \ - "This software contains copyrighted material by:" NEWLINE \ - "The Regents of the University of California" NEWLINE \ - "The NetBSD Foundation, Inc." NEWLINE \ - "Sun Microsystems, Inc." NEWLINE "Ryan Juckett" NEWLINE NEWLINE \ - "Portions of the code have been contributed by:" NEWLINE \ - "Stephen L. Moshier" NEWLINE "Stefan Haubenthal" NEWLINE \ - "Ryan Juckett" NEWLINE "Chris Torek" NEWLINE "Mike Hibler" -/******************************************************************************/ -#endif \ No newline at end of file diff --git a/app/main/functiondefs.h b/app/main/functiondefs.h deleted file mode 100644 index 14a13848..00000000 --- a/app/main/functiondefs.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (c) 2015-2017 Carsten Sonne Larsen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef _FUNCTIONDEFS_H -#define _FUNCTIONDEFS_H - -/** - * @file functiondefs.h - * @brief Function defitions for math logic. - * - */ - -#include "main/nodes.h" -#include "main/functions.h" - -class FunctionNode; -typedef FunctionNode* (*CreateFunctionNode)(ExpressionNode*); - -/** - * @brief Function defitions of known mathematical functions. - * - */ -struct functiondef { - const char *name; - CreateFunctionNode create; -}; - -static const functiondef functiondefs[] = { - { "abs", AbsoluteFunctionNode::Create}, - { "sgn", SignumNode::Create}, - { "round", RoundNode::Create}, - { "trunc", TruncNode::Create}, - { "floor", FloorNode::Create}, - { "ceil", CeilingNode::Create}, - // Supply all variants log and root functions - { "sqr", SquareRootNode::Create}, - { "sqrt", SquareRootNode::Create}, - { "cbr", CubeRootNode::Create}, - { "cbrt", CubeRootNode::Create}, - { "lb", BinaryLogNode::Create}, - { "log2", BinaryLogNode::Create}, - { "ln", LnRootNode::Create}, - { "lg", LogNode::Create}, - { "log", LogNode::Create}, - { "log10", LogNode::Create}, - { "sin", SineNode::Create}, - { "cos", CosineNode::Create}, - { "tan", TangentNode::Create}, - { "cot", CotangentNode::Create}, - { "sec", SecantNode::Create}, - { "csc", CosecantNode::Create}, - // Supply all variants of inverse functions - { "asin", ArcSineNode::Create}, - { "acos", ArcCosineNode::Create}, - { "atan", ArcTangentNode::Create}, - { "acot", ArcCotangentNode::Create}, - { "asec", ArcSecantNode::Create}, - { "acsc", ArcCosecantNode::Create}, - { "arsin", ArcSineNode::Create}, - { "arcos", ArcCosineNode::Create}, - { "artan", ArcTangentNode::Create}, - { "arcot", ArcCotangentNode::Create}, - { "arsec", ArcSecantNode::Create}, - { "arcsc", ArcCosecantNode::Create}, - { "arcsin", ArcSineNode::Create}, - { "arccos", ArcCosineNode::Create}, - { "arctan", ArcTangentNode::Create}, - { "arccot", ArcCotangentNode::Create}, - { "arcsec", ArcSecantNode::Create}, - { "arccsc", ArcCosecantNode::Create}, - { "sinh", HyperbolicSineNode::Create}, - { "cosh", HyperbolicCosineNode::Create}, - { "tanh", HyperbolicTangentNode::Create}, - { "coth", HyperbolicCotangentNode::Create}, - { "sech", HyperbolicSecantNode::Create}, - { "csch", HyperbolicCosecantNode::Create}, - // Supply all variants of inverse functions - { "asinh", HyperbolicArcsineNode::Create}, - { "acosh", HyperbolicArccosineNode::Create}, - { "atanh", HyperbolicArctangentNode::Create}, - { "acoth", HyperbolicArcCotangentNode::Create}, - { "asech", HyperbolicArcSecantNode::Create}, - { "acsch", HyperbolicArcCosecantNode::Create}, - { "arsinh", HyperbolicArcsineNode::Create}, - { "arcosh", HyperbolicArccosineNode::Create}, - { "artanh", HyperbolicArctangentNode::Create}, - { "arcoth", HyperbolicArcCotangentNode::Create}, - { "arsech", HyperbolicArcSecantNode::Create}, - { "arcsch", HyperbolicArcCosecantNode::Create}, - { "arcsinh", HyperbolicArcsineNode::Create}, - { "arccosh", HyperbolicArccosineNode::Create}, - { "arctanh", HyperbolicArctangentNode::Create}, - { "arccoth", HyperbolicArcCotangentNode::Create}, - { "arcsech", HyperbolicArcSecantNode::Create}, - { "arccsch", HyperbolicArcCosecantNode::Create} -}; - -#endif diff --git a/app/main/functions.cpp b/app/main/functions.cpp deleted file mode 100644 index 9d31b5ed..00000000 --- a/app/main/functions.cpp +++ /dev/null @@ -1,1213 +0,0 @@ -/* - * Copyright (c) 2015-2017 Carsten Sonne Larsen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "clib.h" -#include "lib/numb.h" -#include "main/values.h" -#include "main/functions.h" -#include "main/functiondefs.h" -#include "system/program.h" -#include "localize/text.h" - -// ----------------------------------------------------- -// ------------------ FunctionNode --------------------- -// ----------------------------------------------------- - -FunctionNode::FunctionNode(ExpressionNode* expression) : - ExpressionNode(), expression(expression) { } - -FunctionNode::~FunctionNode() -{ - if (expression != NOMEM) { - delete expression; - } -} - -int FunctionNode::GetPrecedence() -{ - return 5; -} - -char* FunctionNode::GetText() -{ - const char *functionText = GetNodeText(); - const char *expText = expression->GetText(); - - output->EnsureSize(StrLen(functionText) + StrLen(expText) + 2 + 1); - output->Empty(); - output->Append(functionText); - output->Append("("); - output->Append(expText); - output->Append(")"); - - return output->GetString(); -} - -SyntaxNode* FunctionNode::GetNext() -{ - if (iterator == NOMEM) { - iterator = expression; - return expression; - } - - return NOMEM; -} - -void FunctionNode::Attach(SyntaxNode* node) -{ - if (expression == NOMEM) { - expression = (ExpressionNode*)node; - node->SetParent(this); - } -} - -void FunctionNode::Detach(SyntaxNode* node) -{ - if (expression == node) { - expression = NOMEM; - } -} - -void FunctionNode::Replace(SyntaxNode* n, SyntaxNode* x) -{ - if (expression == n) { - delete expression; - expression = (ExpressionNode*)x; - } -} - -// ----------------------------------------------------- -// ------------------ UserFunction --------------------- -// ----------------------------------------------------- - -UserFunction::UserFunction(const char *name, const char *variable, ExpressionNode *expression) -{ - AllocAndCopy(&this->name, name); - this->variable = new Variable(variable); - this->expression = expression; - this->Next = NOMEM; - - defname = new CharBuffer(); - defition = new CharBuffer(); - InitializeTexts(); - - chainDelete = true; -} - -UserFunction::UserFunction(const char *name) -{ - AllocAndCopy(&this->name, name); - this->variable = NOMEM; - this->expression = NOMEM; - this->Next = NOMEM; - - defname = new CharBuffer(); - defition = new CharBuffer(); - - chainDelete = true; -} - -UserFunction::~UserFunction() -{ - delete [] name; - delete defname; - delete defition; - - if (variable != NOMEM) { - delete variable; - } - - if (expression != NOMEM) { - delete expression; - } - - if (chainDelete && Next != NOMEM) { - delete Next; - } -} - -void UserFunction::InitializeTexts() -{ - defname->Empty(); - defname->Append(name); - defname->Append('('); - defname->Append(variable != NOMEM ? variable->GetName() : EMPTYSTRING); - defname->Append(')'); - - defition->Empty(); - defition->Append(defname->GetString()); - defition->Append('='); - defition->Append(expression != NOMEM ? expression->GetText() : EMPTYSTRING); -} - -char* UserFunction::GetName() -{ - return name; -} - -char* UserFunction::GetDefitionName() -{ - return defname->GetString(); -} - -char* UserFunction::GetDefitionText() -{ - return defition->GetString(); -} - -Variable* UserFunction::GetVariable() -{ - return variable; -} - -Variable* UserFunction::CreateVariable(const char *name) -{ - if(variable != NOMEM) { - delete variable; - } - - variable = new Variable(name); - InitializeTexts(); - - return variable; -} - -ExpressionNode* UserFunction::GetExpression() -{ - return expression; -} - -void UserFunction::SetExpression(ExpressionNode* expression) -{ - delete this->expression; - this->expression = expression; - InitializeTexts(); -} - -// ----------------------------------------------------- -// ---------------- UserFunctionNode ------------------- -// ----------------------------------------------------- - -UserFunctionNode::UserFunctionNode(UserFunction* function, ExpressionNode* parameter) : - FunctionNode(parameter), function(function) { } - -char* UserFunctionNode::GetNodeText() -{ - return function->GetName(); -} - -Number* UserFunctionNode::Evaluate() -{ - // Set value of function parameter and then evaluate function. - function->GetVariable()->AssignValue(expression->Evaluate()); - return function->GetExpression()->Evaluate(); -} - -SyntaxNode* UserFunctionNode::GetNext() -{ - if (iterator == NOMEM) { - iterator = function->GetExpression(); - return iterator; - } - - return NOMEM; -} - -void UserFunctionNode::Attach(SyntaxNode* node) -{ - // TODO: Implement -} - -void UserFunctionNode::Detach(SyntaxNode* node) -{ - // TODO: Implement -} - -void UserFunctionNode::Replace(SyntaxNode* n, SyntaxNode* x) -{ - // TODO: Implement -} - -// ----------------------------------------------------- -// -------------- FunctionDefinitionNode --------------- -// ----------------------------------------------------- - -FunctionDefinitionNode::FunctionDefinitionNode() : - StatementNode() { - output->EnsureMinimumSize(); - output->Empty(); -} - -char* FunctionDefinitionNode::Execute() -{ - // TODO: Move function definition logic from parser to here. - return output->GetString(); -} - -char* FunctionDefinitionNode::GetText() -{ - return output->GetString(); -} - -// ----------------------------------------------------- -// ------------------ FunctionList --------------------- -// ----------------------------------------------------- - -FunctionList::FunctionList() -{ - first = NOMEM; - buf = new CharBuffer(); -} - -FunctionList::~FunctionList() -{ - if (first != NOMEM) { - delete first; - } - - delete buf; -} - -void FunctionList::Clear() -{ - if (first != NOMEM) { - delete first; - first = NOMEM; - } - - buf->ClearBuffer(); -} - -bool FunctionList::Delete(const char *name, const char *argument) -{ - if (first == NOMEM) - { - return false; - } - - if (first != NOMEM && StrIsEqual(first->GetName(), name) && StrIsEqual(first->GetVariable()->GetName(), argument)) { - UserFunction *func = first; - first = first->Next; - func->chainDelete = false; - delete func; - return true; - } - - UserFunction *current = first->Next; - UserFunction *last = first; - - while (current != NOMEM && !StrIsEqual(current->GetName(), name)) { - current = current->Next; - last = last->Next; - } - - if (current == NOMEM) { - return false; - } else if (!StrIsEqual(current->GetVariable()->GetName(), argument)) { - return false; - } - - last->Next = current->Next; - - // Only delete this variable. Not the whole chain. - current->chainDelete = false; - delete current; - - return true; -} - -UserFunction* FunctionList::GetFirstFunction() -{ - return first; -} - -UserFunction* FunctionList::GetFunctionDef(const char *name) -{ - // Search the list for function definition. If function not found then create a new definition. - if (first == NOMEM) { - first = new UserFunction(name); - return first; - } - - UserFunction *current = first; - UserFunction *last = NOMEM; - - while (current != NOMEM) { - if (StrIsEqual(current->GetName(), name)) { - return current; - } - - last = current; - current = current->Next; - } - - current = new UserFunction(name); - last->Next = current; - - return current; -} - -UserFunction* FunctionList::GetFunctionDef(const char *name, const char *argument) -{ - UserFunction *current = first; - - while (current != NOMEM) { - if (StrIsEqual(current->GetName(), name) && StrIsEqual(current->GetVariable()->GetName(), argument)) { - return current; - } - - current = current->Next; - } - - return NOMEM; -} - -FunctionNode* FunctionList::GetFunctionCall(const char *function, ExpressionNode *parameter) -{ - const functiondef *systemFunction = GetSystemFunction(function); - if (systemFunction != NOMEM) { - return (systemFunction->create)(parameter); - } - - UserFunction *current = first; - while (current != NOMEM && !StrIsEqual(current->GetName(), function)) { - current = current->Next; - } - - if (current != NOMEM) { - return new UserFunctionNode(current, parameter); - } - - return NOMEM; -} - -char* FunctionList::List() -{ - return ListContent(false); -} - -char* FunctionList::ListDefinitions() -{ - return ListContent(true); -} - -char* FunctionList::ListContent(bool cmdFormat) -{ - if (first == NOMEM) { - return (char*)(cmdFormat ? NOMEM : HELPFUNCNDEF); - } - - int len = 0; - UserFunction *current = first; - - while (current != NOMEM) { - len += StrLen(current->GetName()); - len += 1; - len += StrLen(current->GetVariable()->GetName()); - len += 2; - len += StrLen(current->GetExpression()->GetText()); - len += cmdFormat ? 2 : 1; - current = current->Next; - } - - buf->Empty(); - buf->EnsureSize(len + StrLen(NEWLINE) + 1); - - current = first; - while (current != NOMEM) { - buf->Append(current->GetName()); - buf->Append("("); - buf->Append(current->GetVariable()->GetName()); - buf->Append(")="); - buf->Append(current->GetExpression()->GetText()); - - if (cmdFormat) { - buf->Append(';'); - } - - buf->Append(NEWLINE); - current = current->Next; - } - - return buf->GetString(); -} - -bool FunctionList::IsSystemFunction(const char *name) -{ - return (GetSystemFunction(name) != NOMEM); -} - -functiondef* FunctionList::GetSystemFunction(const char *ident) -{ - static const unsigned int count = sizeof(functiondefs) / sizeof(functiondef); - for (unsigned int i = 0; i < count; i++) { - if (StrIsEqual(functiondefs[i].name, ident)) { - return (functiondef*)&functiondefs[i]; - } - } - - return NOMEM; -} - -// ----------------------------------------------------- -// -------------- ListFunctionsStatement --------------- -// ----------------------------------------------------- - -ListFunctionsStatement::ListFunctionsStatement() : - StatementNode() { } - -char* ListFunctionsStatement::Execute() -{ - return Program->Functions->List(); -} - -// ----------------------------------------------------- -// --------------- AbsoluteFunctionNode ---------------- -// ----------------------------------------------------- - -AbsoluteFunctionNode::AbsoluteFunctionNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* AbsoluteFunctionNode::Create(ExpressionNode* expression) -{ - return new AbsoluteFunctionNode(expression); -} - -Number* AbsoluteFunctionNode::Evaluate() -{ - result = expression->Evaluate()->Absolute(); - return result; -} - -char* AbsoluteFunctionNode::GetNodeText() -{ - return (char*)"abs"; -} - -// ----------------------------------------------------- -// --------------------- SignumNode -------------------- -// ----------------------------------------------------- - -SignumNode::SignumNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* SignumNode::Create(ExpressionNode* expression) -{ - return new SignumNode(expression); -} - -Number* SignumNode::Evaluate() -{ - result = expression->Evaluate()->Signum(); - return result; -} - -char* SignumNode::GetNodeText() -{ - return (char*)"sgn"; -} - -// ----------------------------------------------------- -// --------------------- RoundNode --------------------- -// ----------------------------------------------------- - -RoundNode::RoundNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* RoundNode::Create(ExpressionNode* expression) -{ - return new RoundNode(expression); -} - -Number* RoundNode::Evaluate() -{ - result = expression->Evaluate()->Round(); - return result; -} - -char* RoundNode::GetNodeText() -{ - return (char*)"round"; -} - -// ----------------------------------------------------- -// --------------------- TruncNode --------------------- -// ----------------------------------------------------- - -TruncNode::TruncNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* TruncNode::Create(ExpressionNode* expression) -{ - return new TruncNode(expression); -} - -Number* TruncNode::Evaluate() -{ - result = expression->Evaluate()->Trunc(); - return result; -} - -char* TruncNode::GetNodeText() -{ - return (char*)"trunc"; -} - -// ----------------------------------------------------- -// --------------------- FloorNode --------------------- -// ----------------------------------------------------- - -FloorNode::FloorNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* FloorNode::Create(ExpressionNode* expression) -{ - return new FloorNode(expression); -} - -Number* FloorNode::Evaluate() -{ - result = expression->Evaluate()->Floor(); - return result; -} - -char* FloorNode::GetNodeText() -{ - return (char*)"floor"; -} - -// ----------------------------------------------------- -// -------------------- CeilingNode --------------------- -// ----------------------------------------------------- - -CeilingNode::CeilingNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* CeilingNode::Create(ExpressionNode* expression) -{ - return new CeilingNode(expression); -} - -Number* CeilingNode::Evaluate() -{ - result = expression->Evaluate()->Ceiling(); - return result; -} - -char* CeilingNode::GetNodeText() -{ - return (char*)"ceil"; -} - -// ----------------------------------------------------- -// ------------------ SquareRootNode ------------------- -// ----------------------------------------------------- - -SquareRootNode::SquareRootNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* SquareRootNode::Create(ExpressionNode* expression) -{ - return new SquareRootNode(expression); -} - -Number* SquareRootNode::Evaluate() -{ - result = expression->Evaluate()->SquareRoot(); - return result; -} - -char* SquareRootNode::GetNodeText() -{ - return (char*)"sqrt"; -} - -// ----------------------------------------------------- -// ------------------- CubeRootNode -------------------- -// ----------------------------------------------------- - -CubeRootNode::CubeRootNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* CubeRootNode::Create(ExpressionNode* expression) -{ - return new CubeRootNode(expression); -} - -Number* CubeRootNode::Evaluate() -{ - result = expression->Evaluate()->CubeRoot(); - return result; -} - -char* CubeRootNode::GetNodeText() -{ - return (char*)"cbrt"; -} - -// ----------------------------------------------------- -// ------------------ BinaryLogFunction ---------------- -// ----------------------------------------------------- - -BinaryLogNode::BinaryLogNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* BinaryLogNode::Create(ExpressionNode* expression) -{ - return new BinaryLogNode(expression); -} - -Number* BinaryLogNode::Evaluate() -{ - result = expression->Evaluate()->Log2(); - return result; -} - -char* BinaryLogNode::GetNodeText() -{ - return (char*)"lb"; -} - -// ----------------------------------------------------- -// --------------------- LnRootNode -------------------- -// ----------------------------------------------------- - -LnRootNode::LnRootNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* LnRootNode::Create(ExpressionNode* expression) -{ - return new LnRootNode(expression); -} - -Number* LnRootNode::Evaluate() -{ - result = expression->Evaluate()->Log(); - return result; -} - -char* LnRootNode::GetNodeText() -{ - return (char*)"ln"; -} - -// ----------------------------------------------------- -// -------------------- LogRootNode -------------------- -// ----------------------------------------------------- - -LogNode::LogNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* LogNode::Create(ExpressionNode* expression) -{ - return new LogNode(expression); -} - -Number* LogNode::Evaluate() -{ - result = expression->Evaluate()->Log10(); - return result; -} - -char* LogNode::GetNodeText() -{ - return (char*)"lg"; -} - -// ------------------------------------------------------------------------- -// ----------------------- Trigonometric Functions ------------------------- -// ------------------------------------------------------------------------- - -SineNode::SineNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* SineNode::Create(ExpressionNode* expression) -{ - return new SineNode(expression); -} - -Number* SineNode::Evaluate() -{ - result = expression->Evaluate()->Sine(); - return result; -} - -char* SineNode::GetNodeText() -{ - return (char*)"sin"; -} - -CosineNode::CosineNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* CosineNode::Create(ExpressionNode* expression) -{ - return new CosineNode(expression); -} - -Number* CosineNode::Evaluate() -{ - result = expression->Evaluate()->Cosine(); - return result; -} - -char* CosineNode::GetNodeText() -{ - return (char*)"cos"; -} - -TangentNode::TangentNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* TangentNode::Create(ExpressionNode* expression) -{ - return new TangentNode(expression); -} - -Number* TangentNode::Evaluate() -{ - result = expression->Evaluate()->Tangent(); - return result; -} - -char* TangentNode::GetNodeText() -{ - return (char*)"tan"; -} - -CosecantNode::CosecantNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* CosecantNode::Create(ExpressionNode* expression) -{ - return new CosecantNode(expression); -} - -Number* CosecantNode::Evaluate() -{ - result = expression->Evaluate()->Cosecant(); - return result; -} - -char* CosecantNode::GetNodeText() -{ - return (char*)"csc"; -} - -SecantNode::SecantNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* SecantNode::Create(ExpressionNode* expression) -{ - return new SecantNode(expression); -} - -Number* SecantNode::Evaluate() -{ - result = expression->Evaluate()->Secant(); - return result; -} - -char* SecantNode::GetNodeText() -{ - return (char*)"sec"; -} - -CotangentNode::CotangentNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* CotangentNode::Create(ExpressionNode* expression) -{ - return new CotangentNode(expression); -} - -Number* CotangentNode::Evaluate() -{ - result = expression->Evaluate()->Cotangent(); - return result; -} - -char* CotangentNode::GetNodeText() -{ - return (char*)"cot"; -} - -// ------------------------------------------------------------------------- -// -------------------- Inverse Trigonometric Functions -------------------- -// ------------------------------------------------------------------------- - -ArcSineNode::ArcSineNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* ArcSineNode::Create(ExpressionNode* expression) -{ - return new ArcSineNode(expression); -} - -Number* ArcSineNode::Evaluate() -{ - result = expression->Evaluate()->ArcSine(); - return result; -} - -char* ArcSineNode::GetNodeText() -{ - return (char*)"asin"; -} - -ArcCosineNode::ArcCosineNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* ArcCosineNode::Create(ExpressionNode* expression) -{ - return new ArcCosineNode(expression); -} - -Number* ArcCosineNode::Evaluate() -{ - result = expression->Evaluate()->ArcCosine(); - return result; -} - -char* ArcCosineNode::GetNodeText() -{ - return (char*)"acos"; -} - -ArcTangentNode::ArcTangentNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* ArcTangentNode::Create(ExpressionNode* expression) -{ - return new ArcTangentNode(expression); -} - -Number* ArcTangentNode::Evaluate() -{ - result = expression->Evaluate()->ArcTangent(); - return result; -} - -char* ArcTangentNode::GetNodeText() -{ - return (char*)"atan"; -} - -ArcCosecantNode::ArcCosecantNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* ArcCosecantNode::Create(ExpressionNode* expression) -{ - return new ArcCosecantNode(expression); -} - -Number* ArcCosecantNode::Evaluate() -{ - result = expression->Evaluate()->ArcCosecant(); - return result; -} - -char* ArcCosecantNode::GetNodeText() -{ - return (char*)"acsc"; -} - -ArcSecantNode::ArcSecantNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* ArcSecantNode::Create(ExpressionNode* expression) -{ - return new ArcSecantNode(expression); -} - -Number* ArcSecantNode::Evaluate() -{ - result = expression->Evaluate()->ArcSecant(); - return result; -} - -char* ArcSecantNode::GetNodeText() -{ - return (char*)"asec"; -} - -ArcCotangentNode::ArcCotangentNode(ExpressionNode* expression) : - FunctionNode(expression) { } - - -FunctionNode* ArcCotangentNode::Create(ExpressionNode* expression) -{ - return new ArcCotangentNode(expression); -} - -Number* ArcCotangentNode::Evaluate() -{ - result = expression->Evaluate()->ArcCotangent(); - return result; -} - -char* ArcCotangentNode::GetNodeText() -{ - return (char*)"acot"; -} - -// ------------------------------------------------------------------------ -// ------------------------- Hyperbolic Functions ------------------------- -// ------------------------------------------------------------------------ - -HyperbolicSineNode::HyperbolicSineNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* HyperbolicSineNode::Create(ExpressionNode* expression) -{ - return new HyperbolicSineNode(expression); -} - -Number* HyperbolicSineNode::Evaluate() -{ - result = expression->Evaluate()->HypSine(); - return result; -} - -char* HyperbolicSineNode::GetNodeText() -{ - return (char*)"sinh"; -} - -HyperbolicCosineNode::HyperbolicCosineNode(ExpressionNode* expression) - : FunctionNode(expression) { } - -FunctionNode* HyperbolicCosineNode::Create(ExpressionNode* expression) -{ - return new HyperbolicCosineNode(expression); -} - -Number* HyperbolicCosineNode::Evaluate() -{ - result = expression->Evaluate()->HypCosine(); - return result; -} - -char* HyperbolicCosineNode::GetNodeText() -{ - return (char*)"cosh"; -} - -HyperbolicTangentNode::HyperbolicTangentNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* HyperbolicTangentNode::Create(ExpressionNode* expression) -{ - return new HyperbolicTangentNode(expression); -} - -Number* HyperbolicTangentNode::Evaluate() -{ - result = expression->Evaluate()->HypTangent(); - return result; -} - -char* HyperbolicTangentNode::GetNodeText() -{ - return (char*)"tanh"; -} - -HyperbolicCotangentNode::HyperbolicCotangentNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* HyperbolicCotangentNode::Create(ExpressionNode* expression) -{ - return new HyperbolicCotangentNode(expression); -} - -Number* HyperbolicCotangentNode::Evaluate() -{ - result = expression->Evaluate()->HypCotangent(); - return result; -} - -char* HyperbolicCotangentNode::GetNodeText() -{ - return (char*)"coth"; -} - -HyperbolicSecantNode::HyperbolicSecantNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* HyperbolicSecantNode::Create(ExpressionNode* expression) -{ - return new HyperbolicSecantNode(expression); -} - -Number* HyperbolicSecantNode::Evaluate() -{ - result = expression->Evaluate()->HypSecant(); - return result; -} - -char* HyperbolicSecantNode::GetNodeText() -{ - return (char*)"sech"; -} - -HyperbolicCosecantNode::HyperbolicCosecantNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* HyperbolicCosecantNode::Create(ExpressionNode* expression) -{ - return new HyperbolicCosecantNode(expression); -} - -Number* HyperbolicCosecantNode::Evaluate() -{ - result = expression->Evaluate()->HypCosecant(); - return result; -} - -char* HyperbolicCosecantNode::GetNodeText() -{ - return (char*)"csch"; -} - -// ------------------------------------------------------------------------- -// --------------------- Inverse Hyperbolic Functions ---------------------- -// ------------------------------------------------------------------------- - -HyperbolicArcsineNode::HyperbolicArcsineNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* HyperbolicArcsineNode::Create(ExpressionNode* expression) -{ - return new HyperbolicArcsineNode(expression); -} - -Number* HyperbolicArcsineNode::Evaluate() -{ - result = expression->Evaluate()->HypArcSine(); - return result; -} - -char* HyperbolicArcsineNode::GetNodeText() -{ - return (char*)"asinh"; -} - -HyperbolicArccosineNode::HyperbolicArccosineNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* HyperbolicArccosineNode::Create(ExpressionNode* expression) -{ - return new HyperbolicArccosineNode(expression); -} - -Number* HyperbolicArccosineNode::Evaluate() -{ - result = expression->Evaluate()->HypArcCosine(); - return result; -} - -char* HyperbolicArccosineNode::GetNodeText() -{ - return (char*)"acosh"; -} - -HyperbolicArctangentNode::HyperbolicArctangentNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* HyperbolicArctangentNode::Create(ExpressionNode* expression) -{ - return new HyperbolicArctangentNode(expression); -} - -Number* HyperbolicArctangentNode::Evaluate() -{ - result = expression->Evaluate()->HypArcTangent(); - return result; -} - -char* HyperbolicArctangentNode::GetNodeText() -{ - return (char*)"atanh"; -} - -HyperbolicArcCotangentNode::HyperbolicArcCotangentNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* HyperbolicArcCotangentNode::Create(ExpressionNode* expression) -{ - return new HyperbolicArcCotangentNode(expression); -} - -Number* HyperbolicArcCotangentNode::Evaluate() -{ - result = expression->Evaluate()->HypArcCotangent(); - return result; -} - -char* HyperbolicArcCotangentNode::GetNodeText() -{ - return (char*)"acoth"; -} - -HyperbolicArcSecantNode::HyperbolicArcSecantNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* HyperbolicArcSecantNode::Create(ExpressionNode* expression) -{ - return new HyperbolicArcSecantNode(expression); -} - -Number* HyperbolicArcSecantNode::Evaluate() -{ - result = expression->Evaluate()->HypArcSecant(); - return result; -} - -char* HyperbolicArcSecantNode::GetNodeText() -{ - return (char*)"asech"; -} - -HyperbolicArcCosecantNode::HyperbolicArcCosecantNode(ExpressionNode* expression) : - FunctionNode(expression) { } - -FunctionNode* HyperbolicArcCosecantNode::Create(ExpressionNode* expression) -{ - return new HyperbolicArcCosecantNode(expression); -} - -Number* HyperbolicArcCosecantNode::Evaluate() -{ - result = expression->Evaluate()->HypArcCosecant(); - return result; -} - -char* HyperbolicArcCosecantNode::GetNodeText() -{ - return (char*)"acsch"; -} - - diff --git a/app/main/functions.h b/app/main/functions.h deleted file mode 100644 index a064af8c..00000000 --- a/app/main/functions.h +++ /dev/null @@ -1,584 +0,0 @@ -/* - * Copyright (c) 2015-2017 Carsten Sonne Larsen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef _FUNCTIONS_H -#define _FUNCTIONS_H - -/** - * @file functions.h - * @brief Application logic tied to functions. - * - */ - -#include "main/nodes.h" -#include "main/values.h" -#include "main/statements.h" - -/** - * @brief Represents a mathematical function in a syntax tree. - * - * Function nodes in syntax trees can both be well known functions like - * cosine (cos) and also user defined functions. The function node represents - * a function call and not a function definition. - * - * A formal description of mathematical functions can be found at Wikipedia: - * http://en.wikipedia.org/wiki/Function_(mathematics) - * - * When instantiating a function node an argument must be supplied. The argument - * is a pointer to an expression node representing the value which should be used - * when computing the function value. - * - */ -class FunctionNode : public ExpressionNode { -public: - FunctionNode(ExpressionNode* expression); - ~FunctionNode(); - - int GetPrecedence(); - char* GetText(); - virtual SyntaxNode* GetNext(); - virtual void Attach(SyntaxNode *node); - virtual void Detach(SyntaxNode *node); - virtual void Replace(SyntaxNode *n, SyntaxNode *x); - -protected: - ExpressionNode* expression; -}; - -struct functiondef; -class UserFunction; - -/** - * @brief A list of user defined functions. - * - */ -class FunctionList { -public: - FunctionList(); - ~FunctionList(); - - void Clear(); - bool Delete(const char *name, const char *argument); - bool IsSystemFunction(const char *name); - UserFunction* GetFirstFunction(); - UserFunction* GetFunctionDef(const char *name); - UserFunction* GetFunctionDef(const char *name, const char *argument); - FunctionNode* GetFunctionCall(const char *function, ExpressionNode* value); - - char* List(); - char* ListDefinitions(); - -private: - char* ListContent(bool cmdFormat); - CharBuffer *buf; - UserFunction *first; - functiondef *GetSystemFunction(const char *ident); -}; - -/** - * @brief A user defined function. - * - */ -class UserFunction { -public: - UserFunction(const char *name, const char *variable, ExpressionNode *expression); - UserFunction(const char *name); - ~UserFunction(); - - UserFunction *Next; - - char *GetName(); - char *GetDefitionName(); - char *GetDefitionText(); - Variable* GetVariable(); - Variable* CreateVariable(const char *name); - ExpressionNode* GetExpression(); - void SetExpression(ExpressionNode *expression); - -private: - char *name; - Variable *variable; - ExpressionNode *expression; - bool chainDelete; - friend bool FunctionList::Delete(const char *name, const char *argument); - - void InitializeTexts(); - CharBuffer *defname; - CharBuffer *defition; -}; - -/** - * @brief A syntax node able to list all user defined functions. - * - */ -class ListFunctionsStatement : public StatementNode { -public: - ListFunctionsStatement(); - char* Execute(); -}; - -/** - * @brief A syntax node able to define a user defined function. - * - */ -class FunctionDefinitionNode : public StatementNode { -public: - FunctionDefinitionNode(); - char* GetText(); - char* Execute(); -}; - -/** - * @brief An expression node able to compute a function value. - * - */ -class UserFunctionNode : public FunctionNode { -public: - UserFunctionNode(UserFunction* function, ExpressionNode* parameter); - Number* Evaluate(); - SyntaxNode* GetNext(); - void Attach(SyntaxNode *node); - void Detach(SyntaxNode *node); - void Replace(SyntaxNode *n, SyntaxNode *x); - -protected: - char* GetNodeText(); - -private: - UserFunction *function; -}; - -// ----------------------------------------------------- -// ------------------ Odd Functions -------------------- -// ----------------------------------------------------- - -class AbsoluteFunctionNode : public FunctionNode { -public: - AbsoluteFunctionNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -/** - * @brief A signum function in a syntax tree. - * - * Extracts the sign of a real number. See Number for implementation. - * - * More info on the signum function is available at Wikipedia: - * http://en.wikipedia.org/wiki/Sign_function - * - */ -class SignumNode : public FunctionNode { -public: - SignumNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -// ----------------------------------------------------- -// ---------------- Rounding Functions ----------------- -// ----------------------------------------------------- - -/** - * @brief A rounding function in a syntax tree. - * - * Round to nearest integer. See Number for implementation. - * - * More info on the rounding function is available at Wikipedia: - * http://en.wikipedia.org/wiki/Rounding - * - */ -class RoundNode : public FunctionNode { -public: - RoundNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -/** - * @brief A truncation function in a syntax tree. - * - * Discard the number of digits right of the decimal point. - * See Number for implementation. - * - * More info on the truncation function is available at Wikipedia: - * http://en.wikipedia.org/wiki/Truncation - * - */ -class TruncNode : public FunctionNode { -public: - TruncNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class FloorNode : public FunctionNode { -public: - FloorNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class CeilingNode : public FunctionNode { -public: - CeilingNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -// ----------------------------------------------------- -// ------------------ Root Functions ------------------- -// ----------------------------------------------------- - -class SquareRootNode : public FunctionNode { -public: - SquareRootNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class CubeRootNode : public FunctionNode { -public: - CubeRootNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -// ----------------------------------------------------- -// --------------- Logarithmic Functions --------------- -// ----------------------------------------------------- - -class LogNode : public FunctionNode { -public: - LogNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class LnRootNode : public FunctionNode { -public: - LnRootNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class BinaryLogNode : public FunctionNode { -public: - BinaryLogNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -// ----------------------------------------------------- -// ------------- Trigonometric Functions --------------- -// ----------------------------------------------------- - -class SineNode : public FunctionNode { -public: - SineNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class CosineNode : public FunctionNode { -public: - CosineNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class TangentNode : public FunctionNode { -public: - TangentNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class CotangentNode : public FunctionNode { -public: - CotangentNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class CosecantNode : public FunctionNode { -public: - CosecantNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class SecantNode : public FunctionNode { -public: - SecantNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -// ----------------------------------------------------- -// ---------- Inverse Trigonometric Functions ---------- -// ----------------------------------------------------- - -class ArcSineNode : public FunctionNode { -public: - ArcSineNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class ArcCosineNode : public FunctionNode { -public: - ArcCosineNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class ArcTangentNode : public FunctionNode { -public: - ArcTangentNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class ArcCotangentNode : public FunctionNode { -public: - ArcCotangentNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class ArcCosecantNode : public FunctionNode { -public: - ArcCosecantNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class ArcSecantNode : public FunctionNode { -public: - ArcSecantNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -// ----------------------------------------------------- -// --------------- Hyperbolic Functions ---------------- -// ----------------------------------------------------- - -class HyperbolicSineNode : public FunctionNode { -public: - HyperbolicSineNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class HyperbolicCosineNode : public FunctionNode { -public: - HyperbolicCosineNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class HyperbolicTangentNode : public FunctionNode { -public: - HyperbolicTangentNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class HyperbolicCotangentNode : public FunctionNode { -public: - HyperbolicCotangentNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class HyperbolicSecantNode : public FunctionNode { -public: - HyperbolicSecantNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class HyperbolicCosecantNode : public FunctionNode { -public: - HyperbolicCosecantNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -// ----------------------------------------------------- -// ----------- Inverse Hyperbolic Functions ------------ -// ----------------------------------------------------- - -class HyperbolicArccosineNode : public FunctionNode { -public: - HyperbolicArccosineNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class HyperbolicArcsineNode : public FunctionNode { -public: - HyperbolicArcsineNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class HyperbolicArctangentNode : public FunctionNode { -public: - HyperbolicArctangentNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class HyperbolicArcCotangentNode : public FunctionNode { -public: - HyperbolicArcCotangentNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class HyperbolicArcCosecantNode : public FunctionNode { -public: - HyperbolicArcCosecantNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -class HyperbolicArcSecantNode : public FunctionNode { -public: - HyperbolicArcSecantNode(ExpressionNode* expression); - static FunctionNode* Create(ExpressionNode* expression); - Number* Evaluate(); - -protected: - char* GetNodeText(); -}; - -#endif diff --git a/app/main/statements.cpp b/app/main/statements.cpp deleted file mode 100644 index 84d55537..00000000 --- a/app/main/statements.cpp +++ /dev/null @@ -1,884 +0,0 @@ -/* - * Copyright (c) 2015-2017 Carsten Sonne Larsen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "mem.h" -#include "clib.h" -#include "lib/real.h" -#include "lib/charbuf.h" -#include "localize/help.h" -#include "localize/text.h" -#include "localize/start.h" -#include "main/parser.h" -#include "main/graphlist.h" -#include "main/statements.h" -#include "system/console.h" -#include "system/program.h" - -// ----------------------------------------------------- -// ------------------ ClearStatement ------------------- -// ----------------------------------------------------- - -char* ClearStatement::Execute() -{ - Program->Console->Clear(); - return (char*)EMPTYSTRING; -} - -// ----------------------------------------------------- -// ------------------- ExitStatement ------------------- -// ----------------------------------------------------- - -char* ExitStatement::Execute() -{ - Program->Exit(); - return (char*)EMPTYSTRING; -} - -// ----------------------------------------------------- -// ------------------ EmptyStatement ------------------- -// ----------------------------------------------------- - -char* EmptyStatement::Execute() -{ - return (char*)EMPTYSTRING; -} - -// ----------------------------------------------------- -// ----------------- VersionStatement ------------------ -// ----------------------------------------------------- - -char* VersionStatement::Execute() -{ - output->Empty(); - output->EnsureSize( - StrLen(BOLD) + - StrLen(TXTVERSMSG) + - StrLen(NEWLINE) * 2 + - StrLen(NORMALTEXT) + - StrLen(TXTCOMPMSG)); - - output->Append(BOLD); - output->Append(TXTVERSMSG); - output->Append(NORMALTEXT); - output->Append(NEWLINE); - output->Append(TXTCOMPMSG); - output->Append(NEWLINE); - - return output->GetString(); -} - -// ----------------------------------------------------- -// ------------------ PromptStatement ------------------ -// ----------------------------------------------------- - -PromptStatement::PromptStatement(char* prompt) -{ - AllocAndCopy(&this->prompt,prompt); -} - -PromptStatement::~PromptStatement() -{ - delete prompt; -} - -char* PromptStatement::Execute() -{ - CharBuffer *buf = new CharBuffer(); - buf->ClearAndCopy(prompt); - while(buf->RemoveTrailing(' ')); - buf->Append(' '); - Program->SetPrompt(buf->GetString()); - delete buf; - return (char*)EMPTYSTRING; -} - -// ----------------------------------------------------- -// ----------------- PrefsStatement -------------------- -// ----------------------------------------------------- - -PrefsStatement::PrefsStatement() -{ - argument = Symbol(0); -} - -PrefsStatement::PrefsStatement(Symbol argument) -{ - this->argument = argument; -} - -char* PrefsStatement::Execute() -{ - bool success; - - if (argument == symsave) { - success = Program->Preferences->Keep(); - success &= Program->Preferences->Save(); - return (success ? HELPPREFSAVE : HELPPREFNOSA); - } else if (argument == symload) { - success = Program->Preferences->Load(); - - if (success) { - Program->Console->SetPrompt( - Program->Preferences->GetPrompt()); - Program->Input->SetDigits( - Program->Preferences->GetDigits()); - Program->Output->SetDigits( - Program->Preferences->GetDigits()); - return(HELPPREFLOAD); - } else { - return(HELPPREFNOLO); - } - } - - return Program->Preferences->GetDescription(); -} - -// ----------------------------------------------------- -// ----------------- MemoryStatement ------------------ -// ----------------------------------------------------- - -char* MemoryStatement::Execute() -{ - long blocks, size, peak; - MemUsage(&blocks, &size, &peak); - Number *a = new RealNumber((int)blocks); - Number *b = new RealNumber((int)size); - Number *c = new RealNumber((int)peak); - - NumeralSystem *ns = new DecimalSystem(8); - output->Empty(); - output->EnsureSize( - StrLen(TXTMEMBLOCKS) + 8 + - StrLen(TXTMEMSIZE) + 12 + - StrLen(TXTMEMMAXSIZE) + 12); - output->Append(TXTMEMBLOCKS); - output->Append(ns->GetText(a)); - output->Append(NEWLINE); - output->Append(TXTMEMSIZE); - output->Append(ns->GetText(b)); - output->Append(NEWLINE); - output->Append(TXTMEMMAXSIZE); - output->Append(ns->GetText(c)); - output->Append(NEWLINE); - - delete a; - delete b; - delete c; - delete ns; - return output->GetString(); -} - -// ----------------------------------------------------- -// ------------------ SilentStatement ------------------ -// ----------------------------------------------------- - -SilentStatement::SilentStatement(StatementNode* statement) : - statement(statement) { } - -SilentStatement::~SilentStatement() -{ - if (statement != NOMEM) { - delete statement; - } -} - -char* SilentStatement::Execute() -{ - statement->Execute(); - return (char*)EMPTYSTRING; -} - -SyntaxNode* SilentStatement::GetNext() -{ - if (iterator == NOMEM) { - iterator = statement; - return iterator; - } - - return NOMEM; -} - -void SilentStatement::Attach(SyntaxNode* node) -{ - if (statement == NOMEM) { - statement = (StatementNode*)node; - node->SetParent(this); - } -} - -void SilentStatement::Detach(SyntaxNode* node) -{ - if (statement == node) { - statement = NOMEM; - } -} - -void SilentStatement::Replace(SyntaxNode* n, SyntaxNode* x) -{ - if (statement == n) { - delete statement; - statement = (StatementNode*)x; - } -} - -// ----------------------------------------------------- -// ------------------- EvalStatement ------------------- -// ----------------------------------------------------- - -EvalStatement::EvalStatement(ExpressionNode* expression) : - StatementNode(), expression(expression) { } - -EvalStatement::~EvalStatement() -{ - if (expression != NOMEM) { - delete expression; - } -} - -char* EvalStatement::Execute() -{ - Number* result = expression->Evaluate(); - Program->SetLastResult(result); - const char *text = expression->GetText(); - const char *val = Program->Output->GetText(result); - - output->Empty(); - output->EnsureSize( - StrLen(text) + 3 + - StrLen(val) + - StrLen(NEWLINE) + 1); - - output->Append(text); - output->Append(" = "); - output->Append(val); - output->Append(NEWLINE); - - return output->GetString(); -} - -SyntaxNode* EvalStatement::GetNext() -{ - if (iterator == NOMEM) { - iterator = expression; - return iterator; - } - - return NOMEM; -} - -void EvalStatement::Attach(SyntaxNode* node) -{ - if (expression == NOMEM) { - expression = (ExpressionNode*)node; - node->SetParent(this); - } -} - -void EvalStatement::Detach(SyntaxNode* node) -{ - if (expression == node) { - expression = NOMEM; - } -} - -void EvalStatement::Replace(SyntaxNode* n, SyntaxNode* x) -{ - if (expression == n) { - delete expression; - expression = (ExpressionNode*)x; - } -} - -// ----------------------------------------------------- -// ------------------- HelpStatement ------------------- -// ----------------------------------------------------- - -HelpStatement::HelpStatement() : - StatementNode() { - argument = (Symbol)0; - ident = NOMEM; -} - -HelpStatement::HelpStatement(Symbol argument) : - StatementNode(), argument(argument) { - ident = NOMEM; -} - -HelpStatement::HelpStatement(const char *ident) -{ - argument = symident; - AllocAndCopy(&this->ident, ident); -} - -HelpStatement::~HelpStatement() -{ - if (ident != NOMEM) { - delete [] ident; - } -} - -char* HelpStatement::Execute() -{ - char *text = argument != symident ? - Program->Language->GetHelpText(argument) : - Program->Language->GetHelpText(ident); - - output->ClearAndCopy(text); - return output->GetString(); -} - -// ----------------------------------------------------- -// ----------------- DeleteStatement ------------------- -// ----------------------------------------------------- - -/** - * @brief Constructor used to delete either all variable or functions. - * - */ -DeleteStatement::DeleteStatement(Symbol symbol) -{ - type = symbol; - name = NOMEM; - argument = NOMEM; -} - -/** - * @brief Constructor used to delete a Variable. - * - */ -DeleteStatement::DeleteStatement(const char *name) : - StatementNode() -{ - type = symvariable; - AllocAndCopy(&this->name, name); - argument = NOMEM; -} - -/** - * @brief Constructor used to delete a function. - * - */ -DeleteStatement::DeleteStatement(const char *name, const char *argument) : - StatementNode() -{ - type = symfunction; - AllocAndCopy(&this->name, name); - AllocAndCopy(&this->argument, argument); -} - - -DeleteStatement::~DeleteStatement() -{ - if (name != NOMEM) { - delete [] name; - } - - if (argument != NOMEM) { - delete [] argument; - } -} - -char* DeleteStatement::Execute() -{ - bool success = true; - output->Empty(); - - if (type == symvariable && name == NOMEM) { - Program->Variables->Clear(); - } else if (type == symvariable && name != NOMEM) { - success = Program->Variables->Delete(name); - const char *msg = HELPVARNDEF; - - output->EnsureSize( - StrLen(msg) + - StrLen(name) + - StrLen(NEWLINE) + 1); - - output->Append(msg); - output->Append(name); - output->Append(NEWLINE); - - } else if (type == symfunction && name == NOMEM) { - Program->Functions->Clear(); - } else if (type == symfunction && name != NOMEM) { - success = Program->Functions->Delete(name, argument); - const char *msg = HELPFUNNDEF; - - output->EnsureSize( - StrLen(msg) + - StrLen(name) + 2 + - StrLen(argument) + - StrLen(NEWLINE) + 1); - - output->Append(msg); - output->Append(name); - output->Append("("); - output->Append(argument); - output->Append(")"); - output->Append(NEWLINE); - } - - return (char*)(success ? EMPTYSTRING : output->GetString()); -} - -// ----------------------------------------------------- -// ----------------- InputStatement -------------------- -// ----------------------------------------------------- - -/** - * @brief Constructor used to show number of active digits. - * - */ -InputStatement::InputStatement() : - base(0) { } - -/** - * @brief Constructor used to set number of active digits. - * - */ -InputStatement::InputStatement(unsigned int base) : - StatementNode(), base(base) { } - -char* InputStatement::Execute() -{ - const char *text; - - if (base != 0) { - int digits = Program->Input->GetDigits(); - Program->NewPositionalInput(base, digits); - text = HELPINPUSETT; - } else { - text = HELPINPUSHOW; - } - - const char *desc = Program->Input->GetName(); - - output->Empty(); - output->EnsureSize(StrLen(text) + StrLen(desc) + StrLen(NEWLINE) + 1); - output->Append(text); - output->Append(desc); - output->Append(NEWLINE); - return output->GetString(); -} - -// ----------------------------------------------------- -// ----------------- OutputStatement ------------------- -// ----------------------------------------------------- - -/** - * @brief Constructor used to show number of active digits. - * - */ -OutputStatement::OutputStatement() : - base(0) { } - -/** - * @brief Constructor used to set number of active digits. - * - */ -OutputStatement::OutputStatement(unsigned int base) : - StatementNode(), base(base) { } - -char* OutputStatement::Execute() -{ - const char *text; - - if (base != 0) { - int digits = Program->Output->GetDigits(); - Program->NewPositionalOutput(base, digits); - text = HELPOUTPSETT; - } else { - text = HELPOUTPSHOW; - } - - const char *desc = Program->Output->GetName(); - - output->Empty(); - output->EnsureSize(StrLen(text) + StrLen(desc) + StrLen(NEWLINE) + 1); - output->Append(text); - output->Append(desc); - output->Append(NEWLINE); - return output->GetString(); -} - -// ----------------------------------------------------- -// ----------------- DigitsStatement ------------------- -// ----------------------------------------------------- - -/** - * @brief Constructor used to show number of active digits. - * - */DigitsStatement::DigitsStatement() -{ - show = true; -} - -/** - * @brief Constructor used to show number of active digits. - * - */ -DigitsStatement::DigitsStatement(unsigned int digits) : - digits(digits) { - show = false; -} - -char* DigitsStatement::Execute() -{ - const char *text; - - if (!show) { - Program->Input->SetDigits(digits); - Program->Output->SetDigits(digits); - Program->Preferences->SetDigits(digits); - text = HELPDIGISETT; - } else { - text = HELPDIGISHOW; - digits = Program->Output->GetDigits(); - } - - Number *d = new RealNumber(digits); - NumeralSystem *ns = new DecimalSystem(2); - const char *dtext = ns->GetText(d); - delete d; - - output->Empty(); - output->EnsureSize(StrLen(text) + StrLen(dtext) + StrLen(NEWLINE) + 1); - output->Append(text); - output->Append(dtext); - output->Append(NEWLINE); - - delete ns; - return output->GetString(); -} - -// ----------------------------------------------------- -// ------------------ ShowStatement -------------------- -// ----------------------------------------------------- - -ShowStatement::ShowStatement(const char* file) -{ - AllocAndCopy(&this->file, file); -} - -ShowStatement::~ShowStatement() -{ - delete [] file; -} - -char* ShowStatement::Execute() -{ - CharBuffer *text = Program->Filesystem->LoadTextFile(file); - if (text == NOMEM) - { - return (char*)(MSGNOFILE); - } - - delete output; - output = text; - return text->GetString(); -} - -// ----------------------------------------------------- -// ------------------ ListStatement -------------------- -// ----------------------------------------------------- - -ListStatement::ListStatement() : - StatementNode() -{ - directory = NOMEM; -} - -ListStatement::ListStatement(const char *directory) : - StatementNode() -{ - AllocAndCopy(&this->directory, directory); -} - -ListStatement::~ListStatement() -{ - if (directory != NOMEM) { - delete [] directory; - } -} - -char* ListStatement::Execute() -{ - CharBuffer *text = Program->Filesystem->ListDirectory(directory); - if (text == NOMEM) - { - return (char*)(MSGNODIR); - } - - delete output; - output = text; - return text->GetString(); -} - -// ----------------------------------------------------- -// ------------------ LoadStatement -------------------- -// ----------------------------------------------------- - -LoadStatement::LoadStatement(const char *file) -{ - AllocAndCopy(&this->file, file); -} - -LoadStatement::~LoadStatement() -{ - delete [] file; -} - -char* LoadStatement::Execute() -{ - CharBuffer *input = Program->Filesystem->LoadTextFile(file); - if (input == NOMEM) - { - return (char*)(MSGNOFILE); - } - - Parser *parser = new Parser(input->GetString()); - delete input; - - SyntaxNode *node = parser->Parse(); - delete parser; - - node->Execute(); - delete node; - - return (char*)HELPLOADSUCC; -} - -// ----------------------------------------------------- -// ------------------ SaveStatement -------------------- -// ----------------------------------------------------- - -SaveStatement::SaveStatement(const char *file) -{ - AllocAndCopy(&this->file, file); -} - -SaveStatement::~SaveStatement() -{ - delete [] file; -} - -char* SaveStatement::Execute() -{ - const char *vars = Program->Variables->ListDefinitions(); - const char *funcs = Program->Functions->ListDefinitions(); - - if (vars == NOMEM && funcs == NOMEM) { - return (char*)HELPSAVENOTH; - } - - int len = 1; - len += vars != NOMEM ? StrLen(vars) : 0; - len += funcs != NOMEM ? StrLen(funcs) : 0; - - CharBuffer *text = new CharBuffer(len); - text->Empty(); - - if (vars != NOMEM) { - text->Append(vars); - } - if (funcs != NOMEM) { - text->Append(funcs); - } - - bool success = Program->Filesystem->SaveTextFile(file, text->GetString()); - delete text; - - return (char*)(success ? HELPSAVESUCC : HELPSAVEFAIL); -} - -// ----------------------------------------------------- -// ---------------- ExecuteStatement ------------------- -// ----------------------------------------------------- - -ExecuteStatement::ExecuteStatement(const char *file) -{ - AllocAndCopy(&this->file, file); -} - -ExecuteStatement::~ExecuteStatement() -{ - delete [] file; -} - -char* ExecuteStatement::Execute() -{ - CharBuffer *input = Program->Filesystem->LoadTextFile(file); - if (input == NOMEM) - { - return (char*)(MSGNOFILE); - } - - Parser *parser = new Parser(input->GetString()); - delete input; - - SyntaxNode *node = parser->Parse(); - delete parser; - - const char *res = node->Execute(); - output->ClearAndCopy(res); - delete node; - - return output->GetString(); -} - -// ----------------------------------------------------- -// ------------------ PlotStatement -------------------- -// ----------------------------------------------------- - -PlotStatement::PlotStatement(const char* name, const char* parameter, const char* file) : - StatementNode() -{ - AllocAndCopy(&this->name, name); - AllocAndCopy(&this->parameter, parameter); - AllocAndCopy(&this->file, file); -} - -PlotStatement::PlotStatement(const char* name, const char* parameter) : - StatementNode() -{ - AllocAndCopy(&this->name, name); - AllocAndCopy(&this->parameter, parameter); - file = NOMEM; -} - -PlotStatement::~PlotStatement() -{ - delete [] name; - delete [] parameter; - - if (file != NOMEM) { - delete [] file; - } -} - -char* PlotStatement::Execute() -{ - UserFunction *function = Program->Functions->GetFunctionDef(name, parameter); - - if (function == NOMEM) { - return (char*)("Function does not exists." NEWLINE); - } - - output->Empty(); - - Grid *grid = new Grid(function); - static const int width = 400; - static const int height = 300; - - grid->SetScreenBounderues(0, width, 20, height); - bool first = true; - - static const double min = -5.0; - static const double max = +5.0; - grid->SetFunctionBounderies(min, max); - - double x = min; - double step = grid->GetHorizontalResolution(); - - int screenX; - int screenY; - - RealNumber *n = new RealNumber(); - NumeralSystem *ns = new DecimalSystem(5); - - while (x < max) { - grid->GetScreenCoordinates(x, &screenX, &screenY); - - output->EnsureGrowth(32); - - if (screenX != -1 && screenY != -1) { - if (first) { - output->Append('('); - n->SetRealValue(screenX); - output->Append(ns->GetText(n)); - output->Append(','); - n->SetRealValue(height - screenY); - output->Append(ns->GetText(n)); - output->Append(')'); - output->Append(NEWLINE); - first = false; - } else { - output->Append('('); - n->SetRealValue(screenX); - output->Append(ns->GetText(n)); - output->Append(','); - n->SetRealValue(height - screenY); - output->Append(ns->GetText(n)); - output->Append(')'); - output->Append(NEWLINE); - } - } - - x = x + step; - } - - delete n; - delete ns; - - return output->GetString(); -} - -// ----------------------------------------------------- -// ------------------ DrawStatement -------------------- -// ----------------------------------------------------- - -DrawStatement::DrawStatement(const char* name, const char* parameter) -{ - AllocAndCopy(&this->name, name); - AllocAndCopy(&this->parameter, parameter); -} - -DrawStatement::~DrawStatement() -{ - delete [] name; - delete [] parameter; -} - -char* DrawStatement::Execute() -{ - UserFunction *function = Program->Functions->GetFunctionDef(name, parameter); - - if (function == NOMEM) { - return (char*)("Function does not exists." NEWLINE); - } - - GraphWindow *graph = Program->Graphs->CreateNewWindow(); - - if (graph == NOMEM) { - return (char*)"Graphs are not supported in this version."; - } - - graph->OpenGraphWindow(function); - graph->DrawGraph(function); - - return (char*)EMPTYSTRING; -} - diff --git a/app/main/statements.h b/app/main/statements.h deleted file mode 100644 index d9b3854c..00000000 --- a/app/main/statements.h +++ /dev/null @@ -1,326 +0,0 @@ -/* - * Copyright (c) 2015-2017 Carsten Sonne Larsen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef _STATEMENTS_H -#define _STATEMENTS_H - -/** - * @file statements.h - * @brief General statement nodes - * - * This file contains classes implementing statements in a - * syntax tree. All statements inherit from the StatementNode - * base class. - * - */ - -#include "main/nodes.h" -#include "main/token.h" - -/** - * @brief Clear the console window. - * - */ -class ClearStatement : public virtual StatementNode { -public: - ClearStatement() { } - ~ClearStatement() { } - char* Execute(); -}; - -/** - * @brief Exit program. - * - */ -class ExitStatement : public virtual StatementNode { -public: - ExitStatement() { } - ~ExitStatement() { } - char* Execute(); -}; - -/** - * @brief An empty statement. - * - * Statement node which encapsulate an empty statment. This happens - * fx. if the user only enters a line feed. - * - */ -class EmptyStatement : public virtual StatementNode { -public: - EmptyStatement() { } - ~EmptyStatement() { } - char* Execute(); -}; - -/** - * @brief Show version string. - * - */ -class VersionStatement : public virtual StatementNode { -public: - VersionStatement() { } - ~VersionStatement() { } - char* Execute(); -}; - -/** - * @brief Show memory usage. - * - */ -class MemoryStatement : public virtual StatementNode { -public: - MemoryStatement() { } - ~MemoryStatement() { } - char* Execute(); -}; - -/** - * @brief Set prompt string. - * - */ -class PromptStatement : public virtual StatementNode { -public: - PromptStatement(char* prompt); - ~PromptStatement(); - char* Execute(); - -private: - char *prompt; -}; - -/** - * @brief Load or save preferences. - * - */ -class PrefsStatement : public virtual StatementNode { -public: - PrefsStatement(); - PrefsStatement(Symbol argument); - char* Execute(); - -private: - Symbol argument; -}; - -/** - * @brief Mutes the output of another statement. - * - * Statement node which encapsulate another statement and - * mutes the output when executing the inner statement. - * - */ -class SilentStatement : public virtual StatementNode { -public: - SilentStatement(StatementNode *statement); - ~SilentStatement(); - - char* Execute(); - SyntaxNode* GetNext(); - void Attach(SyntaxNode *node); - void Detach(SyntaxNode *node); - void Replace(SyntaxNode *n, SyntaxNode *x); - -private: - StatementNode *statement; -}; - -/** - * @brief Evaluate arithmetic expression. - * - */ -class EvalStatement : public virtual StatementNode { -public: - EvalStatement(ExpressionNode *expression); - ~EvalStatement(); - - char* Execute(); - SyntaxNode* GetNext(); - void Attach(SyntaxNode *node); - void Detach(SyntaxNode *node); - void Replace(SyntaxNode *n, SyntaxNode *x); - -private: - ExpressionNode *expression; -}; - -/** - * @brief Logic related to the help statement. - * - */ -class HelpStatement : public virtual StatementNode { -public: - HelpStatement(); - HelpStatement(Symbol argument); - HelpStatement(const char *ident); - ~HelpStatement(); - char* Execute(); - -private: - Symbol argument; - char *ident; -}; - -/** - * @brief Delete variable or function. - * - */ -class DeleteStatement : public virtual StatementNode { -public: - DeleteStatement(Symbol symbol); - DeleteStatement(const char* name); - DeleteStatement(const char* name, const char *argument); - ~DeleteStatement(); - char* Execute(); - -private: - Symbol type; - char *name; - char *argument; -}; - -/** - * @brief Change numeral input system. - * - */ -class InputStatement : public virtual StatementNode { -public: - InputStatement(); - InputStatement(unsigned int base); - ~InputStatement() { } - char* Execute(); - -private: - unsigned int base; -}; - -/** - * @brief Change numeral output system. - * - */ -class OutputStatement : public virtual StatementNode { -public: - OutputStatement(); - OutputStatement(unsigned int base); - ~OutputStatement() { } - char* Execute(); - -private: - unsigned int base; -}; - -/** - * @brief Set number of significant digits to show. - * - */ -class DigitsStatement : public virtual StatementNode { -public: - DigitsStatement(); - DigitsStatement(unsigned int digits); - ~DigitsStatement() { } - char* Execute(); - -private: - bool show; - unsigned int digits; -}; - -class ShowStatement : public virtual StatementNode { -public: - ShowStatement(const char *file); - ~ShowStatement(); - char* Execute(); - -private: - char *file; -}; - -class ListStatement : public virtual StatementNode { -public: - ListStatement(); - ListStatement(const char *directory); - ~ListStatement(); - char* Execute(); - -private: - char *directory; -}; - -class LoadStatement : public virtual StatementNode { -public: - LoadStatement(const char *file); - ~LoadStatement(); - char* Execute(); - -private: - char *file; -}; - -class SaveStatement : public virtual StatementNode { -public: - SaveStatement(const char *file); - ~SaveStatement(); - char* Execute(); - -private: - char *file; -}; - -class ExecuteStatement : public virtual StatementNode { -public: - ExecuteStatement(const char *file); - ~ExecuteStatement(); - char* Execute(); - -private: - char *file; -}; - -class PlotStatement : public virtual StatementNode { -public: - PlotStatement(const char *name, const char *parameter, const char *file); - PlotStatement(const char *name, const char *parameter); - ~PlotStatement(); - char* Execute(); - -private: - char *name; - char *parameter; - char *file; -}; - -class DrawStatement : public virtual StatementNode { -public: - DrawStatement(const char *name, const char *parameter); - ~DrawStatement(); - char* Execute(); - -private: - char *name; - char *parameter; -}; - -#endif diff --git a/app/system/base/io.cpp b/app/system/base/io.cpp deleted file mode 100644 index f9945509..00000000 --- a/app/system/base/io.cpp +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2015-2017 Carsten Sonne Larsen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "mem.h" -#include "clib.h" -#include "localize/start.h" -#include "system/program.h" -#include "system/program_stdc.h" -#include "system/program_amiga.h" -#include "system/program_test.h" -#include "system/console.h" -#include "system/console_stdc.h" -#include "system/console_amiga.h" -#include "system/language.h" -#include "system/language_stdc.h" -#include "system/language_amiga.h" -#include "system/language_posix.h" -#include "system/filesystem.h" -#include "system/filesystem_stdc.h" -#include "system/filesystem_amiga.h" -#include "system/preferences.h" -#include "system/preferences_stdc.h" -#include "system/preferences_amiga.h" -#include "system/window_amiga.h" -#include "system/graph_amiga.h" -#include "system/base/io.h" - -#ifdef AMIGA -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#else -#include -#endif - -const char *vers = TXTDOSVERSION; -class Program *Program = NULL; -#ifdef AMIGA -static struct DosBase *DosBase = NULL; -static struct GfxBase *GfxBase = NULL; -static struct LocaleBase *LocaleBase = NULL; -static struct IntuitionBase *IntuitionBase = NULL; -#endif - -class Program* CreateProgram(int argc, char **argv) { -#ifdef WITHTEST - if (argc == 2 && StrIsEqual(argv[1], "test")) { - return new TestProgram(); - } else -#endif - { -#ifdef AMIGA - IntuitionBase = (struct IntuitionBase*)OpenLibrary(INTUITION_NAME, INTUITION_REV); - GfxBase = (struct GfxBase*)OpenLibrary(GRAPHICS_NAME, GRAPHICS_REV); - - if (IntuitionBase != NULL && GfxBase != NULL) { - return new AmigaProgram(); - } else { - return new StandardProgram(); - } -#else - return new StandardProgram(); -#endif - } - return NULL; -} - -class Language* CreateLanguage() -{ -#ifdef UNIX - return new PosixLanguage(); -#endif -#ifdef AMIGA - LocaleBase = (struct LocaleBase*)OpenLibrary(LOCALE_NAME, LOCALE_REV); - if (LocaleBase != NULL) { - return new AmigaLanguage(); - } else -#endif - { - return new StandardLanguage(); - } -} - -class PreferencesBase* CreatePreferences() -{ -#ifdef AMIGA - return new AmigaPreferences(); -#else - return new StandardPreferences(); -#endif -} - -class FilesystemBase* CreateFilesystem() -{ -#ifdef AMIGA - DosBase = (struct DosBase*)OpenLibrary(AMIGADOS_NAME, AMIGADOS_REV); - if (DosBase == NULL) { - return NULL; - } - return new AmigaFilesystem(); -#else - return new StandardFilesystem(); -#endif -} - -GraphWindow* CreateGraphWindow() { -#ifdef AMIGA - return new AmigaGraphWindow(); -#else - return NOMEM; -#endif -} - -void WriteToShell(const char *out) { -#ifdef AMIGA - Write(Output(), (APTR)out, StrLen(out)); - Write(Output(), (APTR)NORMALTEXT, StrLen(NORMALTEXT)); -#else - printf("%s%s", out, NORMALTEXT); -#endif -} - -void Cleanup() -{ -#ifdef AMIGA - if (DosBase != NULL) { - CloseLibrary((struct Library*)DosBase); - } - - if (LocaleBase != NULL) { - CloseLibrary((struct Library*)LocaleBase); - } - - if (GfxBase != NULL) { - CloseLibrary((struct Library*)GfxBase); - } - - if (IntuitionBase != NULL) { - CloseLibrary((struct Library*)IntuitionBase); - } -#endif - delete Program; - FreeAllSafe(); -} diff --git a/app/system/base/io.h b/app/system/base/io.h deleted file mode 100644 index 2dc84484..00000000 --- a/app/system/base/io.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2015-2017 Carsten Sonne Larsen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef AMATH_SYSTEM_IO_H -#define AMATH_SYSTEM_IO_H -/******************************************************************************/ -/** - * @file io.h - * @brief System dependent I/O - * - */ -/******************************************************************************/ -#include "clib.h" -#include "platform.h" -#include "system/program.h" - -#define CPROCNAME "amath_console" -/******************************************************************************/ -#ifdef AOS3 -#define AMIGADOS_NAME "dos.library" -#define AMIGADOS_REV 33L -#define INTUITION_REV 37L -#define INTUITION_NAME "intuition.library" -#define GRAPHICS_REV 37L -#define GRAPHICS_NAME "graphics.library" -#define LOCALE_REV 38L -#define LOCALE_NAME "locale.library" -#define DEVCONSOLE "console.device" -#define PORTCR "RKM.console.read" -#define PORTCW "RKM.console.write" -#define CATALOG_HELP "amath-help.catalog" -#define CATALOG_IDEN "amath-ident.catalog" -#define CATALOG_TEXT "amath-text.catalog" -#define CATALOG_KEYW "amath-keyword.catalog" -#define CATALOG_DEF OC_BuiltInLanguage, "english" -#endif -/******************************************************************************/ -#if defined(AROS) || defined(MORPHOS) || defined(AOS4) -#define AMIGADOS_NAME "dos.library" -#define AMIGADOS_REV 33L -#define INTUITION_REV 37L -#define INTUITION_NAME "intuition.library" -#define GRAPHICS_REV 37L -#define GRAPHICS_NAME "graphics.library" -#define LOCALE_REV 38L -#define LOCALE_NAME "locale.library" -#define DEVCONSOLE "console.device" -#define PORTCR "RKM.console.read" -#define PORTCW "RKM.console.write" -#define CATALOG_HELP "amath-help.catalog" -#define CATALOG_IDEN "amath-ident.catalog" -#define CATALOG_TEXT "amath-text.catalog" -#define CATALOG_KEYW "amath-keyword.catalog" -#define CATALOG_DEF OC_BuiltInLanguage, "english" -#endif -/******************************************************************************/ -extern const char *vers; -extern class Program *Program; -class Program* CreateProgram(int,char **); -class Language* CreateLanguage(); -class PreferencesBase* CreatePreferences(); -class FilesystemBase* CreateFilesystem(); -class GraphWindow* CreateGraphWindow(); -void WriteToShell(const char*); -void Cleanup(); -/******************************************************************************/ -#endif diff --git a/app/system/program_test.cpp b/app/system/program_test.cpp deleted file mode 100644 index 728a157d..00000000 --- a/app/system/program_test.cpp +++ /dev/null @@ -1,413 +0,0 @@ -/* - * Copyright (c) 2015-2017 Carsten Sonne Larsen - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifdef WITHTEST -#include "clib.h" -#include "lib/charbuf.h" -#include "main/viewer.h" -#include "main/evaluator.h" -#include "system/program_test.h" -#include "system/base/io.h" -#include - -TestProgram::TestProgram() - : Program() -{ - // Ignore type of locale fraction point. - delete Input; - Input = new DecimalSystem(Preferences->GetDigits(), '.'); - - delete Output; - Output = new DecimalSystem(Preferences->GetDigits(), '.'); -} - -TestProgram::~TestProgram() -{ } - -void TestProgram::Run() -{ - RunTests(); - - if (fail == 0) { - printf("All tests passed (%i)." NEWLINE, pass); - } else { - printf("Something went wrong ..." NEWLINE); - printf("Passed: %i, failed: %i" NEWLINE, pass, fail); - } -} - -void TestProgram::Initialize(int argc, char** argv) -{ - Preferences->Load(); -} - -void TestProgram::Exit() -{ } - -void TestProgram::RunTests() -{ - pass = 0; - fail = 0; - - RunTestset1(); - RunTestset2(); - RunTestset3(); - RunTestset4(); - RunTestset6(); - RunTestset7(); - RunTestset5(); -} - -void TestProgram::TestExpression(const char* expression, const char* result) -{ - PerformTest(expression, result, true, true); -} - -void TestProgram::TestStatement(const char* statement, const char* result) -{ - PerformTest(statement, result, false, true); -} - -void TestProgram::TestExecution(const char* statement) -{ - PerformTest(statement, EMPTYSTRING, false, false); -} - -void TestProgram::PerformTest(const char* input, const char* result, bool show, bool check) -{ - Evaluator *evaluator = new Evaluator(input); - evaluator->Evaluate(); - char *res = evaluator->GetResult(); - - CharBuffer *buf = new CharBuffer(); - buf->ClearAndCopy(res); - buf->RemoveTrailing(NEWLINE); - delete evaluator; - - if (buf->Is(result) || !check) { - pass++; - printf("PASS: [%s]" NEWLINE, show ? result : input); - } else { - fail++; - printf("FAIL: [%s] expected [%s] but got [%s]" NEWLINE, input, result, buf->GetString()); - } - - delete buf; -} - -void TestProgram::RunTestset1() -{ - Input->SetDigits(9); - Output->SetDigits(9); - - TestExpression("-1", "-1 = -1"); - TestExpression("-(-1)", "1 = 1"); - TestExpression("2+3*4+5", "2+3*4+5 = 19"); - TestExpression("(2+3)*(4+5)", "(2+3)*(4+5) = 45"); - TestExpression("-(-2*3)+(-5*3)", "-(-2*3)+(-5)*3 = -9"); - TestExpression("4*5+2*3", "4*5+2*3 = 26"); - TestExpression("(4*5)+(2*3)", "4*5+2*3 = 26"); - TestExpression("(1-1/3+1/5)/(1/2-1/4+1/6)", "(1-1/3+1/5)/(1/2-1/4+1/6) = 2.08"); - TestExpression("1.123456789", "1.12345679 = 1.12345679"); - TestExpression("-1.01234567890123456789", "-1.01234568 = -1.01234568"); - TestExpression("1.1+1.1", "1.1+1.1 = 2.2"); - TestExpression("2.2*2.20", "2.2*2.2 = 4.84"); - TestExpression("3.3/1.1", "3.3/1.1 = 3"); - TestExpression("3.3/1.05", "3.3/1.05 = 3.14285714"); - TestExpression("2^3", "2^3 = 8"); - TestExpression("2^1.5", "2^1.5 = 2.82842712"); - TestExpression("10^3", "10^3 = 1000"); - TestExpression("10.2^1.2", "10.2^1.2 = 16.230063"); - TestExpression("100^0.5", "100^0.5 = 10"); - TestExpression("100^-0.3", "100^(-0.3) = 0.251188643"); - TestExpression("283500/1050", "283500/1050 = 270"); - TestExpression("|1-2|", "|1-2| = 1"); - TestExpression("|1-|1-5||", "|1-|1-5|| = 3"); - TestExpression("sgn(2.3)", "sgn(2.3) = 1"); - TestExpression("sgn(-12.7)", "sgn(-12.7) = -1"); - TestExpression("sgn(0)", "sgn(0) = 0"); - TestExpression("round(1.5461)", "round(1.5461) = 2"); - TestExpression("round(-1.5461)", "round(-1.5461) = -2"); - TestExpression("ceil(43.5461)", "ceil(43.5461) = 44"); - TestExpression("ceil(-43.5461)", "ceil(-43.5461) = -43"); - TestExpression("floor(39.9531)", "floor(39.9531) = 39"); - TestExpression("floor(-39.9531)", "floor(-39.9531) = -40"); - TestExpression("trunc(23.827)", "trunc(23.827) = 23"); - TestExpression("trunc(-23.827)", "trunc(-23.827) = -23"); - TestExpression("log(1000)", "lg(1000) = 3"); - TestExpression("log(100)", "lg(100) = 2"); - TestExpression("log(23.2)", "lg(23.2) = 1.36548798"); - TestExpression("log2(512)", "lb(512) = 9"); - TestExpression("lb(128)", "lb(128) = 7"); - TestExpression("lb(15.32)", "lb(15.32) = 3.93734439"); - TestExpression("ln(103)", "ln(103) = 4.63472899"); - TestExpression("ln(e)", "ln(e) = 1"); - TestExpression("sqrt(100)", "sqrt(100) = 10"); - TestExpression("sqrt(52.23)", "sqrt(52.23) = 7.22703259"); - TestExpression("sqrt(-43.5)", "sqrt(-43.5) = 6.59545298i"); - TestExpression("cbrt(1000)", "cbrt(1000) = 10"); - TestExpression("cbrt(52.23)", "cbrt(52.23) = 3.73800612"); -} - -void TestProgram::RunTestset2() -{ - Input->SetDigits(9); - Output->SetDigits(14); - // 12345678901234 - TestExpression("pi", "pi = 3.1415926535898"); - TestExpression("pi*2", "pi*2 = 6.2831853071796"); - TestExpression("pi/2", "pi/2 = 1.5707963267949"); - TestExpression("cos(pi)", "cos(pi) = -1"); - TestExpression("cos(-pi)", "cos(-pi) = -1"); - TestExpression("cos(pi/2)", "cos(pi/2) = 0"); - TestExpression("sin(pi)", "sin(pi) = 0"); - TestExpression("sin(-pi)", "sin(-pi) = 0"); - TestExpression("sin(pi/2)", "sin(pi/2) = 1"); - TestExpression("tan(pi)", "tan(pi) = 0"); - TestExpression("tan(-pi)", "tan(-pi) = 0"); - TestExpression("tan(pi/2)", "tan(pi/2) = INF"); - // 12345678901234 - TestExpression("cos(0.5)", "cos(0.5) = 0.87758256189037"); - TestExpression("sin(0.5)", "sin(0.5) = 0.4794255386042"); - TestExpression("tan(0.5)", "tan(0.5) = 0.54630248984379"); - TestExpression("cot(0.5)", "cot(0.5) = 1.8304877217125"); - TestExpression("sec(0.5)", "sec(0.5) = 1.1394939273245"); - TestExpression("csc(0.5)", "csc(0.5) = 2.0858296429335"); - TestExpression("arccos(0.35)", "acos(0.35) = 1.2132252231494"); - TestExpression("arcsin(0.35)", "asin(0.35) = 0.35757110364551"); - TestExpression("arctan(0.35)", "atan(0.35) = 0.33667481938673"); - TestExpression("arccot(0.41)", "acot(0.41) = 1.1816990957396"); - TestExpression("arcsec(1.41)", "asec(1.41) = 0.78240533832346"); - TestExpression("arccsc(1.41)", "acsc(1.41) = 0.78839098847143"); - TestExpression("cosh(0.56)", "cosh(0.56) = 1.1609407820725"); - TestExpression("sinh(0.56)", "sinh(0.56) = 0.58973171822364"); - TestExpression("tanh(0.56)", "tanh(0.56) = 0.5079774328979"); - TestExpression("coth(0.56)", "coth(0.56) = 1.9685913885883"); - TestExpression("sech(0.56)", "sech(0.56) = 0.86137037775075"); - TestExpression("csch(0.56)", "csch(0.56) = 1.6956863080252"); - TestExpression("arccosh(1.44)", "acosh(1.44) = 0.90670360498911"); - TestExpression("arcsinh(0.45)", "asinh(0.45) = 0.43604966885174"); - TestExpression("arctanh(0.45)", "atanh(0.45) = 0.48470027859405"); - TestExpression("arccoth(1.51)", "acoth(1.51) = 0.79681365320373"); - TestExpression("arcsech(0.51)", "asech(0.51) = 1.2940148005294"); - TestExpression("arccsch(0.51)", "acsch(0.51) = 1.4259588665675"); -} - -void TestProgram::RunTestset3() -{ - Input->SetDigits(9); - Output->SetDigits(11); - - TestExpression("-(1-2i)", "-(1-2i) = -1+2i"); - TestExpression("-2i-(-3i)", "-2i-(-3i) = 1i"); - TestExpression("1-2i+5.3i-2.1", "1-2i+(-2.1+5.3i) = -1.1+3.3i"); - TestExpression("1-2i+5.3i-2.1+1.3+1.3+1.3i+2/7i", "1-2i+5.3i-2.1+1.3+1.3+1.3i+2/7i = 1.5+4.3142857143i"); - TestExpression("2.3*(2i-1)", "2.3*(-1+2i) = -2.3+4.6i"); - TestExpression("2.3*(2i-1)*3*2i", "2.3*(-1+2i)*3*2i = -27.6-13.8i"); - TestExpression("2.3i*(-1.27)", "2.3i*(-1.27) = -2.921i"); - TestExpression("4.3/3.3i", "4.3/3.3i = -1.303030303i"); - TestExpression("4.3i/3.3", "4.3i/3.3 = 1.303030303i"); - TestExpression("1/(12+7i)", "1/(12+7i) = 0.0621761658-0.03626943005i"); - TestExpression("4.3i/(2.3i+1.1)", "4.3i/(1.1+2.3i) = 1.5215384615+0.72769230769i"); - TestExpression("(2+3.2i)*(4+7i)", "(2+3.2i)*(4+7i) = -14.4+26.8i"); - TestExpression("(2-3i)*(4-7i)", "(2-3i)*(4-7i) = -13-26i"); - TestExpression("(-2+3i)*(-4+7.2i)", "(-2+3i)*(-4+7.2i) = -13.6-26.4i"); - TestExpression("(2+3i)*(-4+7i)", "(2+3i)*(-4+7i) = -29+2i"); - TestExpression("(2.3i+3)/(2.2i+9)", "(3+2.3i)/(9+2.2i) = 0.37348555452+0.16425908667i"); - TestExpression("(2.3i-3)/(2.2i+9)", "(-3+2.3i)/(9+2.2i) = -0.2555917987+0.31803355079i"); - TestExpression("(-2.3i+3)/(2.2i+9)", "(3-2.3i)/(9+2.2i) = 0.2555917987-0.31803355079i"); - TestExpression("(-2.3i-3)/(2.2i+9)", "(-3-2.3i)/(9+2.2i) = -0.37348555452-0.16425908667i"); - TestExpression("(2.3i-3)/(2.2i-9)", "(-3+2.3i)/(-9+2.2i) = 0.37348555452-0.16425908667i"); - TestExpression("(-2.3i+3)/(-2.2i+9)", "(3-2.3i)/(9-2.2i) = 0.37348555452-0.16425908667i"); - TestExpression("(-2.3i-3)/(-2.2i-9)", "(-3-2.3i)/(-9-2.2i) = 0.37348555452+0.16425908667i"); - TestExpression("abs(2.1-3.7i)", "abs(2.1-3.7i) = 4.2544094772"); - TestExpression("abs(-2.1+3.7i)", "abs(-2.1+3.7i) = 4.2544094772"); - TestExpression("abs(-2.1-3.7i)", "abs(-2.1-3.7i) = 4.2544094772"); - TestExpression("sgn(2.1-3.7i)", "sgn(2.1-3.7i) = 1"); - TestExpression("sgn(-2.1+3.7i)", "sgn(-2.1+3.7i) = -1"); - TestExpression("sgn(-2.1-3.7i)", "sgn(-2.1-3.7i) = -1"); - TestExpression("round(1.5461+2.57i)", "round(1.5461+2.57i) = 2+3i"); - TestExpression("round(-1.5461-2.57i)", "round(-1.5461-2.57i) = -2-3i"); - TestExpression("ceil(43.5461+2.57i)", "ceil(43.5461+2.57i) = 44+3i"); - TestExpression("ceil(-43.5461-2.57i)", "ceil(-43.5461-2.57i) = -43-2i"); - TestExpression("floor(39.9531+2.57i)", "floor(39.9531+2.57i) = 39+2i"); - TestExpression("floor(-39.9531-2.57i)", "floor(-39.9531-2.57i) = -40-3i"); - TestExpression("trunc(23.827+2.57i)", "trunc(23.827+2.57i) = 23+2i"); - TestExpression("trunc(-23.827-2.57i)", "trunc(-23.827-2.57i) = -23-2i"); - TestExpression("2^2.2i", "2^2.2i = 0.04585644308+0.99894804i"); - TestExpression("3i^4.4", "3i^4.4 = 101.6930248+73.884307317i"); - TestExpression("(2+4i)^2.2i", "(2+4i)^2.2i = -0.08650199375-0.01340218842i"); - TestExpression("(2-4i)^(2.2i-2)", "(2-4i)^(-2+2.2i) = 0.40864788198-0.39910321822i"); - TestExpression("sqrt(20+50i)", "sqrt(20+50i) = 6.0766622447+4.1141006351i"); - TestExpression("sqrt(20-50i)", "sqrt(20-50i) = 6.0766622447-4.1141006351i"); - TestExpression("sqrt(-20-50i)", "sqrt(-20-50i) = 4.1141006351-6.0766622447i"); - TestExpression("cbrt(120+75i)", "cbrt(120+75i) = 5.1210176499+0.96470708458i"); - TestExpression("cbrt(120-75i)", "cbrt(120-75i) = 5.1210176499-0.96470708458i"); - TestExpression("ln(20+40i)", "ln(20+40i) = 3.8004512298+1.1071487178i"); - TestExpression("ln(20-40i)", "ln(20-40i) = 3.8004512298-1.1071487178i"); - TestExpression("log2(17+35i)", "lb(17+35i) = 5.282074745+1.6138599361i"); - TestExpression("log2(17-35i)", "lb(17-35i) = 5.282074745-1.6138599361i"); - TestExpression("log(20+50i)", "lg(20+50i) = 1.7311989989+0.51693635701i"); - TestExpression("log(20-50i)", "lg(20-50i) = 1.7311989989-0.51693635701i"); -} - -void TestProgram::RunTestset4() -{ - Input->SetDigits(9); - Output->SetDigits(14); - - TestExpression("cos(1+2i)", "cos(1+2i) = 2.0327230070197-3.0518977991518i"); - TestExpression("sin(1+2i)", "sin(1+2i) = 3.1657785132162+1.9596010414216i"); - TestExpression("tan(1+2i)", "tan(1+2i) = 0.0338128260799+1.0147936161466i"); - TestExpression("cot(1+2i)", "cot(1+2i) = 0.03279775553375-0.98432922645819i"); - TestExpression("sec(1+2i)", "sec(1+2i) = 0.15117629826558+0.22697367539372i"); - TestExpression("csc(1+2i)", "csc(1+2i) = 0.22837506559969-0.14136302161241i"); - TestExpression("arccos(1+2i)", "acos(1+2i) = 1.1437177404024-1.528570919481i"); - TestExpression("arcsin(1+2i)", "asin(1+2i) = 0.42707858639248+1.528570919481i"); - TestExpression("arctan(1+2i)", "atan(1+2i) = 1.3389725222945+0.40235947810853i"); - TestExpression("arccot(1+2i)", "acot(1+2i) = 0.2318238045004-0.40235947810853i"); - TestExpression("arcsec(1+2i)", "asec(1+2i) = 1.3844782726871+0.39656823011233i"); - TestExpression("arccsc(1+2i)", "acsc(1+2i) = 0.18631805410782-0.39656823011233i"); - TestExpression("cosh(1+2i)", "cosh(1+2i) = -0.64214812471552+1.0686074213828i"); - TestExpression("sinh(1+2i)", "sinh(1+2i) = -0.48905625904129+1.403119250622i"); - TestExpression("tanh(1+2i)", "tanh(1+2i) = 1.1667362572409-0.24345820118573i"); - TestExpression("coth(1+2i)", "coth(1+2i) = 0.82132979749385+0.17138361290919i"); - TestExpression("sech(1+2i)", "sech(1+2i) = -0.41314934426694-0.68752743865548i"); - TestExpression("csch(1+2i)", "csch(1+2i) = -0.22150093085051-0.6354937992539i"); - TestExpression("arccosh(1+2i)", "acosh(1+2i) = 1.528570919481+1.1437177404024i"); - TestExpression("arcsinh(1+2i)", "asinh(1+2i) = 1.4693517443682+1.0634400235778i"); - TestExpression("arctanh(1+2i)", "atanh(1+2i) = 0.17328679513999+1.1780972450962i"); - TestExpression("arccoth(1+2i)", "acoth(1+2i) = 0.17328679513999-0.39269908169872i"); - TestExpression("arcsech(1+2i)", "asech(1+2i) = 0.39656823011233-1.3844782726871i"); - TestExpression("arccsch(1+2i)", "acsch(1+2i) = 0.21561241855583-0.40158639166781i"); - TestExpression("cos(-1.43-3.23i)", "cos(-1.43-3.23i) = 1.7765430126591-12.495168795382i"); - TestExpression("sin(-1.43-3.23i)", "sin(-1.43-3.23i) = -12.534334855328-1.7709918453308i"); - TestExpression("tan(-1.43-3.23i)", "tan(-1.43-3.23i) = -0.00087228966374-1.003010475525i"); - TestExpression("cot(-1.43-3.23i)", "cot(-1.43-3.23i) = -0.00086706061634+0.99699780617804i"); - TestExpression("sec(-1.43-3.23i)", "sec(-1.43-3.23i) = 0.01115321045915+0.07844518613085i"); - TestExpression("csc(-1.43-3.23i)", "csc(-1.43-3.23i) = -0.07821934898722+0.01105170962818i"); - TestExpression("arccos(-1.43-3.23i)", "acos(-1.43-3.23i) = 1.9733334521871+1.9686290896497i"); - TestExpression("arcsin(-1.43-3.23i)", "asin(-1.43-3.23i) = -0.40253712539219-1.9686290896497i"); - TestExpression("arctan(-1.43-3.23i)", "atan(-1.43-3.23i) = -1.4486945189384-0.26104191221162i"); - TestExpression("arccot(-1.43-3.23i)", "acot(-1.43-3.23i) = -0.1221018078565+0.26104191221162i"); - TestExpression("arcsec(-1.43-3.23i)", "asec(-1.43-3.23i) = 1.6819282086005-0.25760781134815i"); - TestExpression("arccsc(-1.43-3.23i)", "acsc(-1.43-3.23i) = -0.11113188180565+0.25760781134815i"); - TestExpression("cosh(-1.43-3.23i)", "cosh(-1.43-3.23i) = -2.2003770462293-0.17390877229544i"); - TestExpression("sinh(-1.43-3.23i)", "sinh(-1.43-3.23i) = 1.9620027174115+0.19503789026432i"); - TestExpression("tanh(-1.43-3.23i)", "tanh(-1.43-3.23i) = -0.89309335200203-0.01805196156745i"); - TestExpression("coth(-1.43-3.23i)", "coth(-1.43-3.23i) = -1.1192464990635+0.02262316110662i"); - TestExpression("sech(-1.43-3.23i)", "sech(-1.43-3.23i) = -0.4516462791984+0.03569626853807i"); - TestExpression("csch(-1.43-3.23i)", "csch(-1.43-3.23i) = 0.50469595437383-0.05017059012838i"); - TestExpression("arccosh(-1.43-3.23i)", "acosh(-1.43-3.23i) = -1.9686290896497+1.9733334521871i"); - TestExpression("arcsinh(-1.43-3.23i)", "asinh(-1.43-3.23i) = -1.9417349567173-1.1385610418228i"); - TestExpression("arctanh(-1.43-3.23i)", "atanh(-1.43-3.23i) = -0.10773740084981-1.3144779329543i"); - TestExpression("arccoth(-1.43-3.23i)", "acoth(-1.43-3.23i) = -0.10773740084981+0.25631839384056i"); - TestExpression("arcsech(-1.43-3.23i)", "asech(-1.43-3.23i) = -0.25760781134815-1.6819282086005i"); - TestExpression("arccsch(-1.43-3.23i)", "acsch(-1.43-3.23i) = -0.1183123934959+0.2599771870207i"); -} - -void TestProgram::RunTestset5() -{ - TestExecution("delete funtions"); - TestStatement("f(x)=x*2+1", ""); - TestStatement("g(y)=y^2+y*1.5+2", ""); - TestStatement("h(x)=x^3-2*x^2-16*x+6", ""); - TestStatement("a=2;b=3;c=a+b;", ""); - TestStatement("vars", "a = 2" NEWLINE "b = 3" NEWLINE "c = 5"); - TestStatement("funcs", "f(x)=x*2+1" NEWLINE "g(y)=y^2+y*1.5+2" NEWLINE "h(x)=x^3-2*x^2-16*x+6"); - TestStatement("f(2.2)", "f(2.2) = 5.4"); - TestStatement("h(8.3)", "h(8.3) = 307.207"); - TestStatement("c+1.1", "c+1.1 = 6.1"); - TestStatement("d=1.1", ""); - TestStatement("eval d=d+1", "d=(d+1) = 2.1"); - TestStatement("eval d=d+1", "d=(d+1) = 3.1"); - TestStatement("eval d=d*2", "d=(d*2) = 6.2"); - TestStatement("vars", "a = 2" NEWLINE "b = 3" NEWLINE "c = 5" NEWLINE "d = 6.2"); - TestExecution("delete funtions"); - TestExecution("delete variable"); -} - -void TestProgram::RunTestset6() -{ - TestExecution("help"); - TestExecution("help functions"); - TestExecution("help trigon"); - TestExecution("help hyper"); - TestExecution("help complex"); - TestExecution("help statements"); - TestExecution("help operators"); - TestExecution("help sin"); - TestExecution("help help"); - TestExecution("input hex"); - TestExecution("input dec"); - TestExecution("input oct"); - TestExecution("input bin"); - TestExecution("input 25"); - TestExecution("output hex"); - TestExecution("output dec"); - TestExecution("output oct"); - TestExecution("output bin"); - TestExecution("output 25"); - TestExecution("digits 1"); - TestExecution("digits 5"); - TestExecution("digits 9"); - TestExecution("digits 15"); - TestExecution("digits 33"); - TestExecution("input"); - TestExecution("output"); - TestExecution("digits"); - TestExecution("eval 7+7"); - TestExecution("delete x"); - TestExecution("delete pi"); - TestExecution("eval pi/2"); - TestExecution("list"); - TestExecution("memory"); - TestExecution("version"); - TestExecution("variables"); -} - -void TestProgram::RunTestset7() -{ - delete Input; - Input = new DecimalSystem(4, ','); - delete Output; - Output = new DecimalSystem(14, ','); - - TestExpression("cos(0,5)", "cos(0,5) = 0,87758256189037"); - TestExpression("sin(0,5)", "sin(0,5) = 0,4794255386042"); - - delete Output; - Output = new DecimalSystem(14, '.'); - TestExpression("cos(0,5)", "cos(0,5) = 0.87758256189037"); - TestExpression("sin(0,5)", "sin(0,5) = 0.4794255386042"); - - delete Input; - Input = new DecimalSystem(4, '.'); - TestExpression("cos(0.5)", "cos(0.5) = 0.87758256189037"); - TestExpression("sin(0.5)", "sin(0.5) = 0.4794255386042"); -} - -#endif diff --git a/build/debian/control-amd64 b/build/debian/control-amd64 index f58d014a..8752a9dc 100644 --- a/build/debian/control-amd64 +++ b/build/debian/control-amd64 @@ -1,7 +1,7 @@ Package: amath -Version: 1.6.4 +Version: 1.7.0 Architecture: amd64 -Maintainer: Carsten Larsen +Maintainer: Carsten Larsen Installed-Size: 259 Depends: libc6 Section: math diff --git a/build/debian/control-i386 b/build/debian/control-i386 index 131681a2..9126b92f 100644 --- a/build/debian/control-i386 +++ b/build/debian/control-i386 @@ -1,7 +1,7 @@ Package: amath -Version: 1.6.4 +Version: 1.7.0 Architecture: i386 -Maintainer: Carsten Larsen +Maintainer: Carsten Larsen Installed-Size: 262 Depends: libc6 Section: math diff --git a/build/flexcat/configure b/build/flexcat/configure index 4b061348..f01ab1e6 100755 --- a/build/flexcat/configure +++ b/build/flexcat/configure @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2015-2017 Carsten Sonne Larsen +# Copyright (c) 2014-2017 Carsten Sonne Larsen # All rights reserved. # # Redistribution and use in source and binary forms, with or without diff --git a/builddeb.sh b/builddeb similarity index 87% rename from builddeb.sh rename to builddeb index fe5f55d9..b31296ef 100755 --- a/builddeb.sh +++ b/builddeb @@ -1,7 +1,10 @@ -#! /bin/sh +#!/bin/sh # Build a debian package for amd64 +version="1.7.0" + +echo "Building amath ${version} for Debian ..." rm -Rf amath # Build @@ -32,14 +35,14 @@ cp script/* amath/usr/local/share/amath/ # Make the package cp build/debian/control-amd64 amath/DEBIAN/control dpkg-deb --build amath -mv amath.deb amath-1.6.4_amd64.deb +mv amath.deb amath-${version}_amd64.deb # Build a debian package for i386 rm -Rf amath # Build -sh configure -m32 +sh configure cflags="-m32" make clean make mv amath amath.tmp @@ -66,7 +69,7 @@ cp script/* amath/usr/local/share/amath/ # Make the package cp build/debian/control-i386 amath/DEBIAN/control dpkg-deb --build amath -mv amath.deb amath-1.6.4_i386.deb +mv amath.deb amath-${version}_i386.deb # Cleanup #rm -Rf amath diff --git a/builddist b/builddist new file mode 100755 index 00000000..5ff589cb --- /dev/null +++ b/builddist @@ -0,0 +1,116 @@ +#!/bin/sh + +rm -f amath.lha +rm -Rf amath +rm -Rf dist +mkdir dist + +cd build/flexcat +./configure +make clean +make +cd ../.. + +./configure --disable-test --cflags="-m68000 -noixemul" --cross-compile="m68k-amigaos" +make clean +make static +mv amath dist/amath.000 +make clean +./configure --disable-test --cflags="-m68020 -noixemul" --cross-compile="m68k-amigaos" +make static +mv amath dist/amath.020 +make clean +./configure --disable-test --cflags="-m68030 -noixemul" --cross-compile="m68k-amigaos" +make static +mv amath dist/amath.030 +make clean +#./configure --disable-test --cflags="-m68040 -noixemul" --cross-compile="m68k-amigaos" +#make static +#mv amath dist/amath.040 +#make clean +#./configure --disable-test --cflags="-m68060 -noixemul" --cross-compile="m68k-amigaos" +#make static +#mv amath dist/amath.060 +#make clean +#./configure --disable-test --cflags="-m68020 -m68881 -noixemul" --cross-compile="m68k-amigaos" +#make static +#mv amath dist/amath.020f +#make clean +#./configure --disable-test --cflags="-m68030 -m68881 -noixemul" --cross-compile="m68k-amigaos" +#make static +#mv amath dist/amath.030f +#make clean + +./configure --enable-test --cflags="-m68000 -noixemul" --cross-compile="m68k-amigaos" +make static +mv amath dist/amath-test.000 +make clean +./configure --enable-test --cflags="-m68020 -noixemul" --cross-compile="m68k-amigaos" +make static +mv amath dist/amath-test.020 +make clean +./configure --enable-test --cflags="-m68030 -noixemul" --cross-compile="m68k-amigaos" +make static +mv amath dist/amath-test.030 +make clean +#./configure --enable-test --cflags="-m68040 -noixemul" --cross-compile="m68k-amigaos" +#make static +#mv amath dist/amath-test.040 +#make clean +#./configure --enable-test --cflags="-m68060 -noixemul" --cross-compile="m68k-amigaos" +#make static +#mv amath dist/amath-test.060 +#make clean +#./configure --enable-test --cflags="-m68020 -m68881 -noixemul" --cross-compile="m68k-amigaos" +#make static +#mv amath dist/amath-test.020f +#make clean +#./configure --enable-test --cflags="-m68030 -m68881 -noixemul" --cross-compile="m68k-amigaos" +#make static +#mv amath dist/amath-test.030f +#make clean + +cd dist +touch hashkeys +sha1sum amath.000 >>hashkeys +sha1sum amath.020 >>hashkeys +sha1sum amath.030 >>hashkeys +#sha1sum amath.040 >>hashkeys +#sha1sum amath.060 >>hashkeys +#sha1sum amath.020f >>hashkeys +#sha1sum amath.030f >>hashkeys +sha1sum amath-test.000 >>hashkeys +sha1sum amath-test.020 >>hashkeys +sha1sum amath-test.030 >>hashkeys +#sha1sum amath-test.040 >>hashkeys +#sha1sum amath-test.060 >>hashkeys +#sha1sum amath-test.020f >>hashkeys +#sha1sum amath-test.030f >>hashkeys +sha256sum amath.000 >>hashkeys +sha256sum amath.020 >>hashkeys +sha256sum amath.030 >>hashkeys +#sha256sum amath.040 >>hashkeys +#sha256sum amath.060 >>hashkeys +#sha256sum amath.020f >>hashkeys +#sha256sum amath.030f >>hashkeys +sha256sum amath-test.000 >>hashkeys +sha256sum amath-test.020 >>hashkeys +sha256sum amath-test.030 >>hashkeys +#sha256sum amath-test.040 >>hashkeys +#sha256sum amath-test.060 >>hashkeys +#sha256sum amath-test.020f >>hashkeys +#sha256sum amath-test.030f >>hashkeys +cd .. + +make amigacatalogs + +cp LICENSE dist/ +cp HISTORY dist/ + +mkdir dist/script +cp script/* dist/script/ +date -Ru >dist/build_date +#uname -srmo >dist/build_host + +mv dist amath +#lha-ac a amath.lha amath diff --git a/builddist.sh b/builddist.sh deleted file mode 100755 index 8043aaf3..00000000 --- a/builddist.sh +++ /dev/null @@ -1,118 +0,0 @@ -#!/bin/sh - -rm -f amath.lha -rm -Rf amath -rm -Rf dist -mkdir dist - -cd build/flexcat -./configure -make clean -make -cd ../.. - -#GCC295="Y" - -REGTEST="N" ./configure -m68000 m68k-amigaos- -noixemul -make -mv amath dist/amath.000 -make clean -REGTEST="N" ./configure -m68020 m68k-amigaos- -noixemul -make -mv amath dist/amath.020 -make clean -REGTEST="N" ./configure -m68030 m68k-amigaos- -noixemul -make -mv amath dist/amath.030 -make clean -REGTEST="N" ./configure -m68040 m68k-amigaos- -noixemul -make -mv amath dist/amath.040 -make clean -REGTEST="N" ./configure -m68060 m68k-amigaos- -noixemul -make -mv amath dist/amath.060 -make clean -REGTEST="N" ./configure "-m68020 -m68881" m68k-amigaos- -noixemul -make -mv amath dist/amath.020f -make clean -REGTEST="N" ./configure "-m68030 -m68881" m68k-amigaos- -noixemul -make -mv amath dist/amath.030f -make clean - -./configure -m68000 m68k-amigaos- -noixemul -make -mv amath dist/amath-test.000 -make clean -./configure -m68020 m68k-amigaos- -noixemul -make -mv amath dist/amath-test.020 -make clean -./configure -m68030 m68k-amigaos- -noixemul -make -mv amath dist/amath-test.030 -make clean -./configure -m68040 m68k-amigaos- -noixemul -make -mv amath dist/amath-test.040 -make clean -./configure -m68060 m68k-amigaos- -noixemul -make -mv amath dist/amath-test.060 -make clean -./configure "-m68020 -m68881" m68k-amigaos- -noixemul -make -mv amath dist/amath-test.020f -make clean -./configure "-m68030 -m68881" m68k-amigaos- -noixemul -make -mv amath dist/amath-test.030f -make clean - -cd dist -touch hashkeys -sha1sum amath.000 >>hashkeys -sha1sum amath.020 >>hashkeys -sha1sum amath.030 >>hashkeys -sha1sum amath.040 >>hashkeys -sha1sum amath.060 >>hashkeys -sha1sum amath.020f >>hashkeys -sha1sum amath.030f >>hashkeys -sha1sum amath-test.000 >>hashkeys -sha1sum amath-test.020 >>hashkeys -sha1sum amath-test.030 >>hashkeys -sha1sum amath-test.040 >>hashkeys -sha1sum amath-test.060 >>hashkeys -sha1sum amath-test.020f >>hashkeys -sha1sum amath-test.030f >>hashkeys -sha256sum amath.000 >>hashkeys -sha256sum amath.020 >>hashkeys -sha256sum amath.030 >>hashkeys -sha256sum amath.040 >>hashkeys -sha256sum amath.060 >>hashkeys -sha256sum amath.020f >>hashkeys -sha256sum amath.030f >>hashkeys -sha256sum amath-test.000 >>hashkeys -sha256sum amath-test.020 >>hashkeys -sha256sum amath-test.030 >>hashkeys -sha256sum amath-test.040 >>hashkeys -sha256sum amath-test.060 >>hashkeys -sha256sum amath-test.020f >>hashkeys -sha256sum amath-test.030f >>hashkeys -cd .. - -make amigacatalogs - -#cp amath.readme dist/ -cp LICENSE dist/ -cp HISTORY dist/ - -mkdir dist/script -cp script/* dist/script/ -date -Ru >dist/build_date -#uname -srmo >dist/build_host - -mv dist amath -#lha-ac a amath.lha amath diff --git a/buildwin b/buildwin new file mode 100755 index 00000000..aafd9c9d --- /dev/null +++ b/buildwin @@ -0,0 +1,52 @@ +#!/bin/sh + +version="1.7.0" + +echo "Building amath ${version} for Windows ..." + +touch hashkeys +rm -Rf amath +rm -Rf dist +mkdir dist + +./configure --enable-test --cross-compile="i686-w64-mingw32" --cflags="-D_WIN32" --ldflags="-static -static-libgcc -static-libstdc++" +make static +mv amath dist/amath-${version}-x86.exe +make clean + +./configure --enable-test --cross-compile="x86_64-w64-mingw32" --cflags="-D_WIN32" --ldflags="-static -static-libgcc -static-libstdc++" +make static +mv amath dist/amath-${version}-x64.exe +make clean + +./configure --enable-test --cross-compile="i686-w64-mingw32" --cflags="-D_WIN32 -DANSICONSOLE" --ldflags="-static -static-libgcc -static-libstdc++" +make static +mv amath dist/amath-${version}-ansi-x86.exe +make clean + +./configure --enable-test --cross-compile="x86_64-w64-mingw32" --cflags="-D_WIN32 -DANSICONSOLE" --ldflags="-static -static-libgcc -static-libstdc++" +make static +mv amath dist/amath-${version}-ansi-x64.exe +make clean + +cd dist +touch hashkeys +sha1sum amath-${version}-x86.exe >>hashkeys +sha1sum amath-${version}-x86.exe >>hashkeys +sha1sum amath-${version}-ansi-x86.exe >>hashkeys +sha1sum amath-${version}-ansi-x64.exe >>hashkeys +sha256sum amath-${version}-x86.exe >>hashkeys +sha256sum amath-${version}-x86.exe >>hashkeys +sha256sum amath-${version}-ansi-x86.exe >>hashkeys +sha256sum amath-${version}-ansi-x64.exe >>hashkeys +cd .. + +cp LICENSE dist/ +cp HISTORY dist/ + +mkdir dist/script +cp script/* dist/script/ +date -Ru >dist/build_date + +mv dist amath +zip -r amath-${version}.zip amath/* diff --git a/catalog/dansk/amath-help.ct b/catalog/dansk/amath-help.ct index b784b209..9052fadd 100644 --- a/catalog/dansk/amath-help.ct +++ b/catalog/dansk/amath-help.ct @@ -2,7 +2,7 @@ ## language dansk ## codeset 0 ; ############################################################################# -; Copyright (c) 2015-2017 Carsten Sonne Larsen +; Copyright (c) 2014-2017 Carsten Sonne Larsen ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without @@ -30,24 +30,24 @@ ; flexcat catalog/help.cd catalog/danish/amath-help.ct CATALOG catalog/danish/amath-help.catalog ; ############################################################################# symzero -Indtast kommando eller udtryk.#NEWLINE##SYNTAXHIGHLIGHT#Eksempel: 2+3-cos(3)#NORMALTEXT##NEWLINE# #NEWLINE#Mere hjælp er tilgængelig i udvalgte områder#NEWLINE#-------------------------------------------------#NEWLINE#funktioner Grundlæggende funktioner.#NEWLINE#trigo Trigonometriske funktioner.#NEWLINE#hyper Hyperbolske funktioner.#NEWLINE#kompleks Komplekse tal.#NEWLINE#kommandoer Understøttede kommondoer.#NEWLINE#operatorer Understøttede operatorer.#NEWLINE#-------------------------------------------------#NEWLINE##SYNTAXHIGHLIGHT#Eksemple: hjælp trigo#NEWLINE# +Indtast kommando eller udtryk.#NEWLINE##SYNTAXHIGHLIGHT#Eksempel: 2+3-cos(3)#NORMALTEXT##NEWLINE# #NEWLINE#Mere hj�lp er tilg�ngelig i udvalgte omr�der#NEWLINE#-------------------------------------------------#NEWLINE#funktioner Grundl�ggende funktioner.#NEWLINE#trigo Trigonometriske funktioner.#NEWLINE#hyper Hyperbolske funktioner.#NEWLINE#kompleks Komplekse tal.#NEWLINE#kommandoer Underst�ttede kommondoer.#NEWLINE#operatorer Underst�ttede operatorer.#NEWLINE#-------------------------------------------------#NEWLINE##SYNTAXHIGHLIGHT#Eksemple: hj�lp trigo#NEWLINE# symoperator --------------------------------------------------#NEWLINE# + Matematik addition.#NEWLINE# - Matematik subtraktion.#NEWLINE# * Matematik multiplikation.#NEWLINE# / Matematik division.#NEWLINE# ^ Matematik potensopløftning.#NEWLINE# = Tildeling af variabel værdi.#NEWLINE# | Absolutte eller numerisk værdi.#NEWLINE#-------------------------------------------------#NEWLINE# +-------------------------------------------------#NEWLINE# + Matematik addition.#NEWLINE# - Matematik subtraktion.#NEWLINE# * Matematik multiplikation.#NEWLINE# / Matematik division.#NEWLINE# ^ Matematik potensopl�ftning.#NEWLINE# = Tildeling af variabel v�rdi.#NEWLINE# | Absolutte eller numerisk v�rdi.#NEWLINE#-------------------------------------------------#NEWLINE# symfunction --------------------------------------------------#NEWLINE#abs Absolutte eller numerisk værdi.#NEWLINE#sgn Matematik signum funktion.#NEWLINE#round Afrund til nærmeste heltal.#NEWLINE#trunc Fjern decimaler.#NEWLINE#floor Afrund i positiv retning.#NEWLINE#ceil Afrund i negativ retning.#NEWLINE#sqrt Kvadratrodsfunktion (exponent 1/2).#NEWLINE#cbrt Kubikrods (exponent 1/3).#NEWLINE#lb Binær logaritme funktion (grundtal 2).#NEWLINE#ln Naturlig logaritme funktion (grundtal e).#NEWLINE#lg 10-talslogaritme funktion (grundtal 10).#NEWLINE#-------------------------------------------------#NEWLINE##SYNTAXHIGHLIGHT#Eksempel: round(1.55)#NORMALTEXT##NEWLINE# +-------------------------------------------------#NEWLINE#abs Absolutte eller numerisk v�rdi.#NEWLINE#sgn Matematik signum funktion.#NEWLINE#round Afrund til n�rmeste heltal.#NEWLINE#trunc Fjern decimaler.#NEWLINE#floor Afrund i positiv retning.#NEWLINE#ceil Afrund i negativ retning.#NEWLINE#sqrt Kvadratrodsfunktion (exponent 1/2).#NEWLINE#cbrt Kubikrods (exponent 1/3).#NEWLINE#lb Bin�r logaritme funktion (grundtal 2).#NEWLINE#ln Naturlig logaritme funktion (grundtal e).#NEWLINE#lg 10-talslogaritme funktion (grundtal 10).#NEWLINE#-------------------------------------------------#NEWLINE##SYNTAXHIGHLIGHT#Eksempel: round(1.55)#NORMALTEXT##NEWLINE# symtrigon -------------------------------------------------#NEWLINE#sin Trigonometrisk sinus funktion.#NEWLINE#cos Trigonometrisk cosinus funktion.#NEWLINE#tan Trigonometrisk tangent funktion.#NEWLINE#cot Trigonometrisk cotangent funktion.#NEWLINE#sec Trigonometrisk secant funktion.#NEWLINE#csc Trigonometrisk cosecant funktion.#NEWLINE#asin Invers trigonometrisk sinus funktion.#NEWLINE#acos Invers trigonometrisk cosinus funktion.#NEWLINE#atan Invers trigonometrisk tangent funktion.#NEWLINE#acot Invers trigonometrisk cotangent funktion.#NEWLINE#asec Invers trigonometrisk secant funktion.#NEWLINE#acsc Invers trigonometrisk cosecant funktion.#NEWLINE#-------------------------------------------------#NEWLINE#Inverse funktioner kan prefixes med ar eller arc #NEWLINE#i stedet for a.#NEWLINE# symhyper -------------------------------------------------#NEWLINE#sinh Hyperbolsk sinus funktion.#NEWLINE#cosh Hyperbolsk cosinus funktion.#NEWLINE#tanh Hyperbolsk tangent funktion.#NEWLINE#coth Hyperbolsk cotangent funktion.#NEWLINE#sech Hyperbolsk secant funktion.#NEWLINE#csch Hyperbolsk cosecant funktion. #NEWLINE#asinh Invers hyperbolsk sinus funktion.#NEWLINE#acosh Invers hyperbolsk cosinus funktion.#NEWLINE#atanh Invers hyperbolsk tangent funktion.#NEWLINE#acoth Invers hyperbolsk cotangent funktion.#NEWLINE#asech Invers hyperbolsk secant funktion.#NEWLINE#acsch Invers hyperbolsk cosecant funktion.#NEWLINE#-------------------------------------------------#NEWLINE#Inverse funktioner kan prefixes med ar eller arc #NEWLINE#i stedet for a.#NEWLINE# ; Table of statements symstatement -----------------------------------------------------------------------#NEWLINE#ryd Ryd konsol vindue.#NEWLINE#definer Definer funktion.#NEWLINE#slet Slet variabler og funktioner.#NEWLINE#cifre Angiv antal betydende cifre.#NEWLINE#beregn Beregn aritmetiske udtryk.#NEWLINE#kør Afvikel kommondoer i en fil.#NEWLINE#funktioner Vis liste med brugerdefinerede funktioner.#NEWLINE#ind Skift numerisk talsystem ved læsning (eksperimentelt).#NEWLINE#hjælp Vis grundlæggende hjælpetekst.#NEWLINE#ud Skift numerisk talsystem ved skrivning (eksperimentelt).#NEWLINE#list Vis indholdet af en mappe.#NEWLINE#vis Vis indholdet af en fil.#NEWLINE#hent Hent variabler og funktioner fra en fil.#NEWLINE#gem Gem variabler og funktioner til en fil.#NEWLINE#variabler Vis variabler i hukommelsen.#NEWLINE#version Vis infomation om denne version.#NEWLINE#hukommelse Vis internt hukommelsesforbrug.#NEWLINE#afslut Afslut program.#NEWLINE#----------------------------------------------------------------------#NEWLINE#Det er valgfrit at angive definer og beregn kommandoerne. Kommandoerne#NEWLINE#funktioner og variabler kan forkortes til funk og var.#NEWLINE# +----------------------------------------------------------------------#NEWLINE#ryd Ryd konsol vindue.#NEWLINE#definer Definer funktion.#NEWLINE#slet Slet variabler og funktioner.#NEWLINE#cifre Angiv antal betydende cifre.#NEWLINE#beregn Beregn aritmetiske udtryk.#NEWLINE#k�r Afvikel kommondoer i en fil.#NEWLINE#funktioner Vis liste med brugerdefinerede funktioner.#NEWLINE#ind Skift numerisk talsystem ved l�sning (eksperimentelt).#NEWLINE#hj�lp Vis grundl�ggende hj�lpetekst.#NEWLINE#ud Skift numerisk talsystem ved skrivning (eksperimentelt).#NEWLINE#list Vis indholdet af en mappe.#NEWLINE#vis Vis indholdet af en fil.#NEWLINE#hent Hent variabler og funktioner fra en fil.#NEWLINE#gem Gem variabler og funktioner til en fil.#NEWLINE#variabler Vis variabler i hukommelsen.#NEWLINE#version Vis infomation om denne version.#NEWLINE#hukommelse Vis internt hukommelsesforbrug.#NEWLINE#afslut Afslut program.#NEWLINE#----------------------------------------------------------------------#NEWLINE#Det er valgfrit at angive definer og beregn kommandoerne. Kommandoerne#NEWLINE#funktioner og variabler kan forkortes til funk og var.#NEWLINE# symcomplex -Udtryk med komplekse tal skrives ved at angive i#NEWLINE#sammen med den imaginære talværdi. Komplekse tal#NEWLINE#kan blandes med reelle tal.#NEWLINE##SYNTAXHIGHLIGHT#Syntaks: 2+3i#NEWLINE#Eksempel: 2+3.2i*cos(-1i)+5/7#NEWLINE# +Udtryk med komplekse tal skrives ved at angive i#NEWLINE#sammen med den imagin�re talv�rdi. Komplekse tal#NEWLINE#kan blandes med reelle tal.#NEWLINE##SYNTAXHIGHLIGHT#Syntaks: 2+3i#NEWLINE#Eksempel: 2+3.2i*cos(-1i)+5/7#NEWLINE# symclear Ryd kommandoen sletter alt tekst i konsol vinduet.#NEWLINE##SYNTAXHIGHLIGHT#Syntaks: ryd#NEWLINE# symdef -Definer kommandoen bruges til at definere funktioner med. Det er ikke#NEWLINE#strengt nødvendigt at angive kommandoen, når en funktion skal defineres.#NEWLINE#Allerede definerede funktioner kan vises med kommandoen #SYNTAXHIGHLIGHT#funtioner#NORMAL#.#NEWLINE##SYNTAXHIGHLIGHT#Syntaks: definer f(x)=2*x+3#NEWLINE#Alternativ syntaks: f(x)=2*x+3#NEWLINE# +Definer kommandoen bruges til at definere funktioner med. Det er ikke#NEWLINE#strengt n�dvendigt at angive kommandoen, n�r en funktion skal defineres.#NEWLINE#Allerede definerede funktioner kan vises med kommandoen #SYNTAXHIGHLIGHT#funtioner#NORMAL#.#NEWLINE##SYNTAXHIGHLIGHT#Syntaks: definer f(x)=2*x+3#NEWLINE#Alternativ syntaks: f(x)=2*x+3#NEWLINE# ; Help for delete statement symdelete The delete statement can delete variable and funktions. To delete a#NEWLINE#single variable or funktions use the name of the funktion or variable.#NEWLINE#To delete all funktions or variables specify either the variable or#NEWLINE#funktion keyword.#NEWLINE##SYNTAXHIGHLIGHT#Syntaks: delete f(x)#NEWLINE#Syntaks: delete variables#NEWLINE# @@ -73,15 +73,15 @@ The output statement either changes or shows the how numeral output is shown.#NE symlist No description is available for the list statement.#NEWLINE# symshow -Vis kommandoen kan bruges til at vise indholdet af en fil, der ønskes kørt.#NEWLINE##SYNTAXHIGHLIGHT#Syntaks: vis "mitscript"#NEWLINE# +Vis kommandoen kan bruges til at vise indholdet af en fil, der �nskes k�rt.#NEWLINE##SYNTAXHIGHLIGHT#Syntaks: vis "mitscript"#NEWLINE# ; Help for load statement symload The load statement retrieves a set of defined variables and funktions from#NEWLINE#a file. Variables and funktions can be saved using the save statement.#NEWLINE##SYNTAXHIGHLIGHT#Syntaks: load "savedwork"#NEWLINE# ; Help for save statement symsave -Med gem kommando kan variabler og funktioner i hukommelsen gemmes til en fil.#NEWLINE#Gemte variabler og funktion kan indlæstet igen med #SYNTAXHIGHLIGHT#hent#NORMAL# kommandoen.#NEWLINE##SYNTAXHIGHLIGHT#Syntaks: gem "mitarbejde"#NEWLINE# +Med gem kommando kan variabler og funktioner i hukommelsen gemmes til en fil.#NEWLINE#Gemte variabler og funktion kan indl�stet igen med #SYNTAXHIGHLIGHT#hent#NORMAL# kommandoen.#NEWLINE##SYNTAXHIGHLIGHT#Syntaks: gem "mitarbejde"#NEWLINE# symversion -Viser hvilken version af amath der kører.#NEWLINE# +Viser hvilken version af amath der k�rer.#NEWLINE# symmem Viser internt hukommelsesforbrug. Programkoden er ikke medregnet.#NEWLINE# ; Help for prefs statement @@ -98,14 +98,14 @@ Euler's number is base of the exponential funktion which equals its own#NEWLINE# sympi Pi is the ratio of the circumference of a circle to its diameter. Being an#NEWLINE#irrational number, pi cannot be expressed exactly as a common fraction.#NEWLINE#The value of pi is commonly approximated as #SYNTAXHIGHLIGHT#3.14159#NORMALTEXT#.#NEWLINE# symi -Den imaginære enhen refereres og angives almindelig vis som i.#NEWLINE#Den imaginære enhen et tal, som når det ganges med sig selv,#NEWLINE#giver resultatet -1.#NEWLINE# +Den imagin�re enhen refereres og angives almindelig vis som i.#NEWLINE#Den imagin�re enhen et tal, som n�r det ganges med sig selv,#NEWLINE#giver resultatet -1.#NEWLINE# symins -Den sidst udregnede værdi kan benyttes i næste udtryk ved hjælp af #SYNTAXHIGHLIGHT#ins#NORMAL# variablen.#NEWLINE##SYNTAXHIGHLIGHT#Eksemple: ins*0,25#NEWLINE# +Den sidst udregnede v�rdi kan benyttes i n�ste udtryk ved hj�lp af #SYNTAXHIGHLIGHT#ins#NORMAL# variablen.#NEWLINE##SYNTAXHIGHLIGHT#Eksemple: ins*0,25#NEWLINE# symbin -Der er ikke nogen hjælp tilgængelig om binær nøgleordet.#NEWLINE +Der er ikke nogen hj�lp tilg�ngelig om bin�r n�gleordet.#NEWLINE symoct -Der er ikke nogen hjælp tilgængelig om oktal nøgleordet.#NEWLINE +Der er ikke nogen hj�lp tilg�ngelig om oktal n�gleordet.#NEWLINE symdec -Der er ikke nogen hjælp tilgængelig om decimal nøgleordet.#NEWLINE +Der er ikke nogen hj�lp tilg�ngelig om decimal n�gleordet.#NEWLINE symhex -Der er ikke nogen hjælp tilgængelig om hexadecimal nøgleordet.#NEWLINE +Der er ikke nogen hj�lp tilg�ngelig om hexadecimal n�gleordet.#NEWLINE diff --git a/catalog/dansk/amath-keyword.ct b/catalog/dansk/amath-keyword.ct index da5564cc..25459fba 100644 --- a/catalog/dansk/amath-keyword.ct +++ b/catalog/dansk/amath-keyword.ct @@ -2,7 +2,7 @@ ## language dansk ## codeset 0 ;############################################################################# -; Copyright (c) 2015-2017 Carsten Sonne Larsen +; Copyright (c) 2014-2017 Carsten Sonne Larsen ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without @@ -58,7 +58,7 @@ plot plot ;######### ExecuteStatement execute -kør +k�r ;######### ExitStatement exit afslut @@ -90,7 +90,7 @@ hyperbolic hyperbolsk ;######### HelpStatement help -hjælp +hj�lp ;######### PromptStatement prompt prompt @@ -104,9 +104,9 @@ memory hukommelse ;######### PrefsStatement prefs -præf +pr�f preferences -præferencer +pr�ferencer ;######### ListStatement and keyword list list @@ -137,7 +137,7 @@ ud bin bin binary -binær +bin�r ;######### Octal keyword oct okt diff --git a/catalog/dansk/amath-text.ct b/catalog/dansk/amath-text.ct index a7815765..b0ef4800 100644 --- a/catalog/dansk/amath-text.ct +++ b/catalog/dansk/amath-text.ct @@ -2,7 +2,7 @@ ## language dansk ## codeset 0 ; ############################################################################# -; Copyright (c) 2015-2017 Carsten Sonne Larsen +; Copyright (c) 2014-2017 Carsten Sonne Larsen ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without @@ -27,7 +27,7 @@ ; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ; ############################################################################# INTROMSG -#NORMALTEXT##BOLD##STARTMSG##NEWLINE##NORMALTEXT##COLOR02#Skriv hjælp for at få vist uddybende information.#NEWLINE# +#NORMALTEXT##BOLD##STARTMSG##NEWLINE##NORMALTEXT##COLOR02#Skriv hj�lp for at f� vist uddybende information.#NEWLINE# TXTLISTDIRHEADER Type Navn#NEWLINE#-----------------------------------------------#NEWLINE# TXTLISTDIRTFILE @@ -41,9 +41,9 @@ Allokerede blokke: #SPACE# TXTMEMSIZE Hukommelsesforbrug:#SPACE# TXTMEMMAXSIZE -Højeste forbrug: #SPACE# +H�jeste forbrug: #SPACE# HELPNOHELP -Der er ingen hjælp tilgængelig om det emne.#NEWLINE# +Der er ingen hj�lp tilg�ngelig om det emne.#NEWLINE# HELPSYNTAX Syntaktiske fejl:#SPACE# HELPUERROR @@ -55,19 +55,19 @@ Funktionen er ikke defineret:#SPACE# HELPFUNRDEF Funktionen er allerede defineret:#SPACE# HELPPNUMERA -Grundtallet skal være mellem 2 og 32:#SPACE# +Grundtallet skal v�re mellem 2 og 32:#SPACE# HELPPDIGITS -Antal betydende cifre skal være mellem 0 og 15:#SPACE# +Antal betydende cifre skal v�re mellem 0 og 15:#SPACE# HELPINPUSHOW -Talsystemet når computeren læser ind er#SPACE# +Talsystemet n�r computeren l�ser ind er#SPACE# HELPOUTPSHOW -Talsystemet når computeren skriver ud er#SPACE# +Talsystemet n�r computeren skriver ud er#SPACE# HELPINPUSETT -Talsystemet ved indlæsning ændret til#SPACE# +Talsystemet ved indl�sning �ndret til#SPACE# HELPOUTPSETT -Talsystemet ved udskrivning ændret til#SPACE# +Talsystemet ved udskrivning �ndret til#SPACE# HELPDIGISETT -Antal betydende cifre ændret til#SPACE# +Antal betydende cifre �ndret til#SPACE# HELPDIGISHOW Antal betydende cifre der vises er#SPACE# HELPVARSNDEF @@ -75,7 +75,7 @@ Der er ikke defineret nogle variabler.#NEWLINE# HELPFUNCNDEF Der er ikke defineret nogle funktioner.#NEWLINE# HELPLOADSUCC -Variabler og funktioner indlæst fra fil.#NEWLINE# +Variabler og funktioner indl�st fra fil.#NEWLINE# HELPSAVESUCC Variabler og funktioner gemt til fil.#NEWLINE# HELPSAVEFAIL @@ -83,14 +83,14 @@ Kan ikke gemme fil.#NEWLINE# HELPSAVENOTH Der er ikke noget og gemme.#NEWLINE# HELPPREFLOAD -Præferencer blev indlæst.#NEWLINE# +Pr�ferencer blev indl�st.#NEWLINE# HELPPREFNOLO -Kunne ikke indlæses præferencer.#NEWLINE# +Kunne ikke indl�ses pr�ferencer.#NEWLINE# HELPPREFSAVE -Præferencer blev gemt.#NEWLINE# +Pr�ferencer blev gemt.#NEWLINE# HELPPREFNOSA -Kunne ikke gemme præferencer.#NEWLINE# +Kunne ikke gemme pr�ferencer.#NEWLINE# MSGNODIR -Mappen kan ikke åbnes:#SPACE# +Mappen kan ikke �bnes:#SPACE# MSGNOFILE -Filen kan ikke åbnes.#NEWLINE# +Filen kan ikke �bnes.#NEWLINE# diff --git a/catalog/english/amath-help.ct b/catalog/english/amath-help.ct index da7bf6c3..8eb94b25 100644 --- a/catalog/english/amath-help.ct +++ b/catalog/english/amath-help.ct @@ -2,7 +2,7 @@ ## language english ## codeset 0 ; ############################################################################# -; Copyright (c) 2015-2017 Carsten Sonne Larsen +; Copyright (c) 2014-2017 Carsten Sonne Larsen ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without @@ -46,7 +46,7 @@ symhyper -------------------------------------------------#NEWLINE#sinh Hyperbolic sine function.#NEWLINE#cosh Hyperbolic cosine function.#NEWLINE#tanh Hyperbolic tangent function.#NEWLINE#coth Hyperbolic cotangent function.#NEWLINE#sech Hyperbolic secant function.#NEWLINE#csch Hyperbolic cosecant function. #NEWLINE#asinh Inverse hyperbolic sine function.#NEWLINE#acosh Inverse hyperbolic cosine function.#NEWLINE#atanh Inverse hyperbolic tangent function.#NEWLINE#acoth Inverse hyperbolic cotangent function.#NEWLINE#asech Inverse hyperbolic secant function.#NEWLINE#acsch Inverse hyperbolic cosecant function.#NEWLINE#-------------------------------------------------#NEWLINE#Inverse functions can be prefixed with ar or arc #NEWLINE#instead of a.#NEWLINE# ; Table of statements symstatement ----------------------------------------------------------#NEWLINE#clear Clear console window.#NEWLINE#def Define function.#NEWLINE#delete Delete variable or function.#NEWLINE#digits Set number of significant digits.#NEWLINE#eval Evaluate arithmetic expression.#NEWLINE#execute Execute statements in a file.#NEWLINE#functions Show list of user defined functions.#NEWLINE#input Change numeral input system (experimental).#NEWLINE#help Show basic help text.#NEWLINE#output Change numeral output system (experimental).#NEWLINE#list Show content of a directory.#NEWLINE#show Show content of a file.#NEWLINE#load Load variable and functions from file.#NEWLINE#save Save variable and functions to file.#NEWLINE#variables Show list of variables.#NEWLINE#version Show version string.#NEWLINE#memory Show internal memory usage.#NEWLINE#exit Exit program.#NEWLINE#---------------------------------------------------------#NEWLINE#The def and eval statements are optional. Functions and#NEWLINE#variables statements can be shorten to funcs and vars.#NEWLINE# +---------------------------------------------------------#NEWLINE#clear Clear console window.#NEWLINE#def Define function.#NEWLINE#delete Delete variable or function.#NEWLINE#digits Set number of significant digits.#NEWLINE#eval Evaluate arithmetic expression.#NEWLINE#execute Execute statements in a file.#NEWLINE#functions Show list of user defined functions.#NEWLINE#input Change numeral input system.#NEWLINE#help Show basic help text.#NEWLINE#output Change numeral output system.#NEWLINE#list Show content of a directory.#NEWLINE#show Show content of a file.#NEWLINE#load Load variable and functions from file.#NEWLINE#save Save variable and functions to file.#NEWLINE#variables Show list of variables.#NEWLINE#version Show version string.#NEWLINE#memory Show internal memory usage.#NEWLINE#exit Exit program.#NEWLINE#---------------------------------------------------------#NEWLINE#The def and eval statements are optional. Functions and#NEWLINE#variables statements can be shorten to funcs and vars.#NEWLINE# ; Help for complex numbers symcomplex Expressions with complex numbers are written using an i to denote#NEWLINE#the imaginary value. Complex numbers can seamlessly be mixed with#NEWLINE#real numbers.#NEWLINE##SYNTAXHIGHLIGHT#Syntax: 2+3i#NEWLINE#Example: 2+3.2i*cos(-1i)+5/7#NEWLINE# diff --git a/catalog/english/amath-ident.ct b/catalog/english/amath-ident.ct index 9db1eaef..36e9452a 100644 --- a/catalog/english/amath-ident.ct +++ b/catalog/english/amath-ident.ct @@ -8,18 +8,18 @@ ;## This file is published under Creative Common License. See: ;## http://creativecommons.org/licenses/by-sa/3.0/ ;## Parts of the content came from wikipedia.org: -;## http://en.wikipedia.org/wiki/Wikipedia:Copyrights#Re-use_of_text +;## https://wikipedia.org/wiki/Wikipedia:Copyrights#Re-use_of_text ;############################################################################# -; Partly from http://en.wikipedia.org/wiki/Absolute_value +; Partly from https://wikipedia.org/wiki/Absolute_value abs The absolute value (or modulus) |x| of a real number x is the#NEWLINE#non-negative value of x without regard to its sign.#NEWLINE##SYNTAXHIGHLIGHT#Example: abs(-237.25)#NORMALTEXT##NEWLINE# -; Partly from http://en.wikipedia.org/wiki/Sign_function +; Partly from https://wikipedia.org/wiki/Sign_function sgn The sign function or signum function is used to extract the sign of a number.#NEWLINE#Thus sgn(x) is 1 when x is positive, and sgn(x) is -1 when x is negative.#NEWLINE##SYNTAXHIGHLIGHT#Example: sgn(-23.94)#NORMALTEXT##NEWLINE# -; Partly from http://en.wikipedia.org/wiki/Rounding +; Partly from https://wikipedia.org/wiki/Rounding round Rounding a numerical value means replacing it by another value that is#NEWLINE#approximately equal but has a shorter, simpler, or more explicit#NEWLINE#representation. Amath rounds a number to the nearest integer.#NEWLINE# -; Partly from http://en.wikipedia.org/wiki/Rounding +; Partly from https://wikipedia.org/wiki/Rounding trunc Truncation is limiting the number of digits right of the decimal point,#NEWLINE#by discarding the least significant ones. Amath truncates a number to#NEWLINE#the nearest integer.#NEWLINE##SYNTAXHIGHLIGHT#Example: trunc(-23.94#NEWLINE# floor @@ -36,13 +36,13 @@ ln No help is available for this function.#NEWLINE# lg No help is available for this function.#NEWLINE# -; Partly from http://en.wikipedia.org/wiki/Sine +; Partly from https://wikipedia.org/wiki/Sine sin Sine is the trigonometric function that for an acute angle is the#NEWLINE#ratio between the leg opposite the angle when it is considered#NEWLINE#part of a right triangle and the hypotenuse.#NEWLINE# -; Partly from http://en.wikipedia.org/wiki/Trigonometric_functions +; Partly from https://wikipedia.org/wiki/Trigonometric_functions cos Cosine is the trigonometric function that for an acute angle is the#NEWLINE#ratio between the leg adjacent to the angle when it is considered#NEWLINE#part of a right triangle and the hypotenuse#NEWLINE# -; Partly from http://en.wikipedia.org/wiki/Trigonometric_functions +; Partly from https://wikipedia.org/wiki/Trigonometric_functions tan Tangent is one of the trigonometry functions. In a right triangle,#NEWLINE#the tangent of an angle is the opposite side over the adjacent side.#NEWLINE# cot diff --git a/catalog/english/amath-text.ct b/catalog/english/amath-text.ct index 1fdbdf22..ea579251 100644 --- a/catalog/english/amath-text.ct +++ b/catalog/english/amath-text.ct @@ -2,7 +2,7 @@ ## language english ## codeset 0 ; ############################################################################# -; Copyright (c) 2015-2017 Carsten Sonne Larsen +; Copyright (c) 2014-2017 Carsten Sonne Larsen ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without diff --git a/configure b/configure index 98d7eefd..c3910a8e 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2015-2017 Carsten Sonne Larsen +# Copyright {c} 2014-2017 Carsten Sonne Larsen # All rights reserved. # # Redistribution and use in source and binary forms, with or without @@ -17,375 +17,848 @@ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# DAMAGES {INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION} # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# LIABILITY, OR TORT {INCLUDING NEGLIGENCE OR OTHERWISE} ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # set -e +clang=false +debugsym=false +regtest=true + +prefix="/usr" +cflags="" +cxxflags="" +ldflags="" +gcclib="-lstdc++" + +for arg in "$@"; do + case "$arg" in + --prefix=*) + prefix=`echo $arg | sed 's/--prefix=//'` + ;; + + --cross-compile=*) + crosscompile=`echo $arg | sed 's/--cross-compile=//'` + crosscompile="${crosscompile}-" + ;; + + --cflags=*) + cflags=`echo $arg | sed 's/--cflags=//'` + cflags="${cflags} " + ;; + + --cxxflags=*) + cxxflags=`echo $arg | sed 's/--cxxflags=//'` + cxxflags="${cxxflags} " + ;; + + --ldflags=*) + ldflags=`echo $arg | sed 's/--ldflags=//'` + ldflags="${ldflags} " + ;; + + --enable-clang) + clang=true;; + --disable-clang) + clang=false;; + + --enable-debug) + debugsym=true;; + --disable-debug) + debugsym=false;; + + --enable-test) + regtest=true;; + --disable-test) + regtest=false;; + + --help) + echo 'usage: ./configure [options]' + echo 'options:' + echo ' --prefix=: installation prefix' + echo ' --cflag=: additional compiler flags' + echo ' --cxxflag=: additional compiler flags' + echo ' --ldflag=: additional linker flags' + echo ' --cross-compile=: cross compiler prefix' + echo ' --enable-debug: include debug symbols' + echo ' --disable-debug: do not include debug symbols' + echo ' --enable-test: build code with regression tests' + echo ' --disable-test: do not include regression test' + echo ' --enable-clang: build with clang compiler' + echo ' --disable-clang: do not build with clang compiler' + echo 'all invalid options are silently ignored' + exit 0 + ;; + esac +done + +if $clang; then + ccompiler="clang" + cxxcompiler="clang++" +else + ccompiler="gcc" + cxxcompiler="g++" +fi + +if $regtest; then + options=" -DWITHTEST" +else + options=" " +fi + +if $debugsym; then + appop="-O0 -g" + libop="-O0 -g" + exestrip="" +else + appop="-O2" + libop="-O3" + exestrip="-s" +fi + +cxxflags="${cflags} ${cxxflags}" + APPSRCS=' - app/main/evaluator.cpp - app/main/functions.cpp - app/main/graphlist.cpp - app/main/lexer.cpp - app/main/nodes.cpp - app/main/operators.cpp - app/main/optimizer.cpp - app/main/parser.cpp - app/main/statements.cpp - app/main/token.cpp - app/main/values.cpp - app/main/viewer.cpp - app/system/console.cpp - app/system/console_amiga.cpp - app/system/console_stdc.cpp - app/system/filesystem_amiga.cpp - app/system/filesystem_stdc.cpp - app/system/graph.cpp - app/system/graph_amiga.cpp - app/system/graph_gtk.cpp - app/system/language.cpp - app/system/language_amiga.cpp - app/system/language_posix.cpp - app/system/language_stdc.cpp - app/system/preferences.cpp - app/system/preferences_amiga.cpp - app/system/preferences_stdc.cpp - app/system/proc_amiga.cpp - app/system/program.cpp - app/system/program_amiga.cpp - app/system/program_stdc.cpp - app/system/program_test.cpp - app/system/task_amiga.cpp - app/system/task_stdc.cpp - app/system/window_amiga.cpp - app/system/base/io.cpp - app/main.cpp +evaluator.cpp +functionlist.cpp +functions.cpp +fgrid.cpp +lexer.cpp +nodes.cpp +operators.cpp +optimizer.cpp +parser.cpp +token.cpp +userfunction.cpp +values.cpp +viewer.cpp +' +SYSSRCS=' +console.cpp +console_amiga.cpp +console_stdc.cpp +filesystem_amiga.cpp +filesystem_stdc.cpp +graph.cpp +graph_amiga.cpp +graph_gtk.cpp +language.cpp +language_amiga.cpp +language_posix.cpp +language_stdc.cpp +preferences.cpp +preferences_amiga.cpp +preferences_stdc.cpp +proc_amiga.cpp +program.cpp +program_amiga.cpp +program_stdc.cpp +program_test.cpp +task_amiga.cpp +task_stdc.cpp +window_amiga.cpp +' +FUNCTIONSRC=' +absolute.cpp +aexcosecant.cpp +aexsecant.cpp +arccos.cpp +arcsin.cpp +arctan.cpp +arccosecant.cpp +arccotangent.cpp +arcsecant.cpp +ceil.cpp +cosecant.cpp +cosine.cpp +cotangent.cpp +covercos.cpp +coversin.cpp +cube.cpp +excosecant.cpp +exsecant.cpp +floor.cpp +hacovercos.cpp +hacoversin.cpp +havercos.cpp +haversin.cpp +ln.cpp +log10.cpp +log2.cpp +node.cpp +round.cpp +secant.cpp +signum.cpp +sine.cpp +square.cpp +tangent.cpp +trunc.cpp +user.cpp +vercos.cpp +versin.cpp +' +STATEMENTSRCS=' +about.cpp +clear.cpp +delete.cpp +digits.cpp +draw.cpp +empty.cpp +eval.cpp +execute.cpp +exit.cpp +funcdef.cpp +funclist.cpp +help.cpp +input.cpp +license.cpp +list.cpp +load.cpp +memory.cpp +node.cpp +output.cpp +plot.cpp +prefs.cpp +prompt.cpp +save.cpp +show.cpp +silent.cpp +version.cpp ' LIBAPPSRCS=' - app/lib/aengine.cpp - app/lib/charbuf.cpp - app/lib/cplex.cpp - app/lib/fgrid.cpp - app/lib/ntext.cpp - app/lib/real.cpp +aengine.cpp +charbuf.cpp +integer.cpp +cplex.cpp +nnumb.cpp +ntext.cpp +real.cpp ' LIBREALSRCS=' - lib/real/acos.c - lib/real/acosh.c - lib/real/asin.c - lib/real/asinh.c - lib/real/atan.c - lib/real/atan2.c - lib/real/atanh.c - lib/real/cbrt.c - lib/real/ceil.c - lib/real/copysign.c - lib/real/cos.c - lib/real/cosh.c - lib/real/exp.c - lib/real/expm1.c - lib/real/fabs.c - lib/real/finite.c - lib/real/floor.c - lib/real/fmod.c - lib/real/hypot.c - lib/real/isnan.c - lib/real/kcos.c - lib/real/kremp2.c - lib/real/ksin.c - lib/real/ktan.c - lib/real/log.c - lib/real/log10.c - lib/real/log1p.c - lib/real/pow.c - lib/real/remp2.c - lib/real/round.c - lib/real/scalbn.c - lib/real/sin.c - lib/real/sinh.c - lib/real/sqrt.c - lib/real/tan.c - lib/real/tanh.c - lib/real/trunc.c +acos.c +acosh.c +acvs.c +ahv.c +ahvc.c +asin.c +asinh.c +atan.c +atan2.c +atanh.c +aver.c +cbrt.c +ceil.c +copysign.c +cos.c +cosh.c +exp.c +expm1.c +fabs.c +finite.c +floor.c +fmod.c +hypot.c +isnan.c +kcos.c +kremp2.c +ksin.c +ktan.c +log.c +log10.c +log1p.c +pow.c +remp2.c +round.c +scalbn.c +sin.c +sinh.c +sqrt.c +tan.c +tanh.c +trunc.c ' LIBCPLEXSRCS=' - lib/cplex/cacos.c - lib/cplex/cacosh.c - lib/cplex/cacot.c - lib/cplex/cacoth.c - lib/cplex/cacsc.c - lib/cplex/cacsch.c - lib/cplex/casec.c - lib/cplex/casech.c - lib/cplex/casin.c - lib/cplex/casinh.c - lib/cplex/catan.c - lib/cplex/catanh.c - lib/cplex/ccbrt.c - lib/cplex/ccos.c - lib/cplex/ccosh.c - lib/cplex/ccot.c - lib/cplex/ccoth.c - lib/cplex/ccsc.c - lib/cplex/ccsch.c - lib/cplex/cexp.c - lib/cplex/clog.c - lib/cplex/clog10.c - lib/cplex/clogb.c - lib/cplex/cpow.c - lib/cplex/csec.c - lib/cplex/csech.c - lib/cplex/csgn.c - lib/cplex/csin.c - lib/cplex/csinh.c - lib/cplex/csqrt.c - lib/cplex/ctan.c - lib/cplex/ctanh.c - lib/cplex/prim.c +cacos.c +cacosh.c +cacot.c +cacoth.c +cacsc.c +cacsch.c +casec.c +casech.c +casin.c +casinh.c +catan.c +catanh.c +ccbrt.c +ccos.c +ccosh.c +ccot.c +ccoth.c +ccsc.c +ccsch.c +cexp.c +clog.c +clog10.c +clogb.c +cpow.c +csec.c +csech.c +csgn.c +csin.c +csinh.c +csqrt.c +ctan.c +ctanh.c +prim.c ' LIBC1SRCS=' - lib/clib/alloccpy.c - lib/clib/mem.c - lib/clib/memcpy.c - lib/clib/memset.c - lib/clib/strcmp.c - lib/clib/strlen.c - lib/clib/untag.c +alloccpy.c +mem.c +memcpy.c +memset.c +strcmp.c +strlen.c +untag.c ' -LIBC2SRCS=' - lib/dconv/dragon4.cpp - lib/dconv/dmath.cpp - lib/dconv/dprint.cpp - lib/clib/memoo.cpp -' +amathc="amathc" +amath="amath" +amathcplex="amathcplex" +amathapp="amathapp" -if make -v 2>&1 | grep GNU > /dev/null 2>&1 ; then - echo "make(1) is GNU make." - VALID=true -else - echo "make(1) is not GNU make." - VALID=true -fi +appmain="appmain" +appfunction="functions" +appstatement="statement" +appsystem="appsystem" +program="src/main" -if $VALID ; then - if [ -n "$1" ]; - then - ARCFLAG="$1 " - else - ARCFLAG="" - fi +############################ Main Application ########################### +{ +echo "CXX = ${crosscompile}${cxxcompiler}" +echo "CXXFLAGS = ${appop}${options} ${cxxflags}-I. -I.. -Wall" +echo "AR = ${crosscompile}ar" +echo "RANLIB = ${crosscompile}ranlib" +echo "DEL = rm -f" +echo +echo "all: lib" +echo "static: lib" +echo - if [ -n "$2" ]; - then - CROSSCOMPILE="$2" - else - CROSSCOMPILE="" - fi +files="" +for f in ${APPSRCS} +do + b=`basename $f .cpp` + echo "${b}.o: ${f}" + echo " \${CXX} \${CXXFLAGS} -c ${f}" + echo + files="${files} ${b}.o" +done - if [ -n "$3" ]; - then - CROSSCOMPILEFLAGS="$3 " - else - CROSSCOMPILEFLAGS="" - fi +echo "lib: ${files}" +echo " \${AR} rcs lib${appmain}.a ${files}" +echo " \${RANLIB} lib${appmain}.a" +echo +echo "clean:" +echo " \${DEL} lib${appmain}.a ${files}" +echo +} > src/main/Makefile +######################################################################### - if [ -n "$GCC295" ]; - then - if [ "$GCC295" = "y" ] || [ "$GCC295" = "Y" ]; - then - gcclib="-lgcc" - fi - else - gcclib="-lstdc++" - fi +########################### Functions Library ########################### +{ +echo "CXX = ${crosscompile}${cxxcompiler}" +echo "CXXFLAGS = ${appop}${options} ${cxxflags}-I. -I../.. -Wall" +echo "AR = ${crosscompile}ar" +echo "RANLIB = ${crosscompile}ranlib" +echo "DEL = rm -f" +echo +echo "all: lib" +echo "static: lib" +echo - if [ -n "$REGTEST" ]; - then - if [ "$REGTEST" = "n" ] || [ "$REGTEST" = "N" ]; - then - options="${options}" - fi - else - options="${options} -DWITHTEST" - fi +files="" +for f in ${FUNCTIONSRC} +do + b=`basename $f .cpp` + echo "${b}.o: ${f}" + echo " \${CXX} \${CXXFLAGS} -c ${f}" + echo + files="${files} ${b}.o" +done - if [ -n "$DEBUG" ]; - then - if [ "$DEBUG" = "y" ] || [ "$DEBUG" = "Y" ]; - then - appop="-O0 -g" - libop="-O0 -g" - exestrip="" - fi - else - appop="-O2" - libop="-O3" - exestrip="-s" - fi +echo "lib: ${files}" +echo " \${AR} rcs lib${appfunction}.a ${files}" +echo " \${RANLIB} lib${appfunction}.a" +echo +echo "clean:" +echo " \${DEL} lib${appfunction}.a ${files}" +echo +} > src/main/function/Makefile +######################################################################### - # Use under certain circumstances when GCC is causing problems with FPU - #nff="-fno-strict-aliasing -ffloat-store " - nff=" " +########################### Statement Library ########################### +{ +echo "CXX = ${crosscompile}${cxxcompiler}" +echo "CXXFLAGS = ${appop}${options} ${cxxflags}-I. -I../.. -Wall" +echo "AR = ${crosscompile}ar" +echo "RANLIB = ${crosscompile}ranlib" +echo "DEL = rm -f" +echo +echo "all: lib" +echo "static: lib" +echo - ( - echo - echo "CC = ${CROSSCOMPILE}gcc" - echo "CXX = ${CROSSCOMPILE}g++" -# echo "CC = ${CROSSCOMPILE}clang" -# echo "CXX = ${CROSSCOMPILE}clang++" - echo "AR = ${CROSSCOMPILE}ar" - echo "RANLIB = ${CROSSCOMPILE}ranlib" - echo "CFLAGS = ${ARCFLAG}$options ${CROSSCOMPILEFLAGS}" - echo "CXXFLAGS = ${ARCFLAG}$options ${CROSSCOMPILEFLAGS}-I." - echo "LFLAGS = -lamathapp${outext} -lcomplex${outext} -lamath${outext} -lcamath${outext} $gcclib" - echo - echo "FLXCAT = build/flexcat/flexcat" - echo "MKDIR = mkdir -p" - echo "COPY = cp" - echo "DEL = rm -f" - echo - echo "all: libs app" - echo - echo "libs: libamath libcomplex libcamath libamathapp" +files="" +for f in ${STATEMENTSRCS} +do + b=`basename $f .cpp` + echo "${b}.o: ${f}" + echo " \${CXX} \${CXXFLAGS} -c ${f}" echo + files="${files} ${b}.o" +done - i="" - l="" - for f in ${APPSRCS} - do - b=`basename $f .cpp` -# i=`sed -n -e '/#include.*"/{ -# s/"$// -# s/.*"// -# p -# }' $f | sort -u` - echo "${b}.o: ${f}" ${i} - echo " \${CXX} ${appop} \${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c ${f}" - echo - l="${l} ${b}.o" - done +echo "lib: ${files}" +echo " \${AR} rcs lib${appstatement}.a ${files}" +echo " \${RANLIB} lib${appstatement}.a" +echo +echo "clean:" +echo " \${DEL} lib${appstatement}.a ${files}" +echo +} > src/main/statement/Makefile +######################################################################### - libapp="" - for f in ${LIBAPPSRCS} - do - b=`basename $f .cpp` - echo "${b}.o: ${f}" - echo " \${CC} ${appop} \${CXXFLAGS} -Ilib -Iapp -Wall -Werror -c ${f}" - echo - libapp="${libapp} ${b}.o" - done +############################ System Library ############################# +{ +echo "CXX = ${crosscompile}${cxxcompiler}" +echo "CXXFLAGS = ${appop}${options} ${cxxflags}-I. -I.. -Wall" +echo "AR = ${crosscompile}ar" +echo "RANLIB = ${crosscompile}ranlib" +echo "DEL = rm -f" +echo +echo "all: lib" +echo "static: lib" +echo - libamath="" - for f in ${LIBREALSRCS} - do - b=`basename $f .c` - echo "${b}.o: ${f}" - echo " \${CC} ${libop} -std=c9x \${CLAGS} ${ARCFLAG}-fno-builtin ${nff}-Wall -Werror -Ilib -Ilib/real -c ${f}" - echo - libamath="${libamath} ${b}.o" - done +files="" +for f in ${SYSSRCS} +do + b=`basename $f .cpp` + echo "${b}.o: ${f}" + echo " \${CXX} \${CXXFLAGS} -c ${f}" + echo + files="${files} ${b}.o" +done - libcomplex="" - for f in ${LIBCPLEXSRCS} - do - b=`basename $f .c` - echo "${b}.o: ${f}" - echo " \${CC} ${libop} -std=c9x \${CFLAGS} ${ARCFLAG}-fno-builtin -Wall -Werror -Ilib -Ilib/cplex -c ${f}" - echo - libcomplex="${libcomplex} ${b}.o" - done +echo "lib: ${files}" +echo " \${AR} rcs lib${appsystem}.a ${files}" +echo " \${RANLIB} lib${appsystem}.a" +echo +echo "clean:" +echo " \${DEL} lib${appsystem}.a ${files}" +echo +} > src/system/Makefile +######################################################################### - libc="" - for f in ${LIBC1SRCS} - do - b=`basename $f .c` - echo "${b}.o: ${f}" - echo " \${CC} ${libop} -std=c9x \${CFLAGS} ${ARCFLAG}${ansicon}-fno-builtin -Wall -Werror -Ilib -c ${f}" - echo - libc="${libc} ${b}.o" - done +########################## Application Library ########################## +{ +echo "CXX = ${crosscompile}${cxxcompiler}" +echo "CXXFLAGS = ${libop}${options} ${cxxflags}-I. -I.. -Wall" +echo "AR = ${crosscompile}ar" +echo "RANLIB = ${crosscompile}ranlib" +echo "MKDIR = mkdir -p" +echo "DEL = rm -f" +echo "INSTALL = install -m 0644" +echo "PREFIX = ${prefix}" +echo +echo "alib = lib${amathapp}.a" +echo "solib = lib${amathapp}.so" +echo +echo "all: static shared" +echo +echo "static: \${alib}" +echo +echo "shared: \${solib}" +echo - for f in ${LIBC2SRCS} - do - b=`basename $f .cpp` - echo "${b}.o: ${f}" - echo " \${CXX} ${libop} \${CXXFLAGS} ${ARCFLAG}-fno-builtin -Wall -Werror -Ilib -Ilib/dconv -c ${f}" - echo - libc="${libc} ${b}.o" - done +files="" +files2="" +for f in ${LIBAPPSRCS} +do + b=`basename $f .cpp` + echo "static/${b}.o: ${f}" + echo " \${CXX} \${CXXFLAGS} -c ${f} -o static/${b}.o" + echo + echo "shared/${b}.o: ${f}" + echo " \${CXX} \${CXXFLAGS} -fPIC -c ${f} -o shared/${b}.o" + echo + files="${files} static/${b}.o" + files2="${files2} shared/${b}.o" +done - echo "catalogsa:" # Application catalogs - echo " \${FLXCAT} text/keyword.cd app/localize/kword.h=text/keyword.sd" - echo " \${FLXCAT} text/help.cd app/localize/help.h=text/help.sd" - echo " \${FLXCAT} text/ident.cd app/localize/ident.h=text/ident.sd" - echo " \${FLXCAT} text/text.cd app/localize/text.h=text/text.sd" - echo - echo "catalogsu:" # Unix catalogs - echo " iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-help.ct >utext/dk-help.dict" - echo " iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-ident.ct >utext/dk-ident.dict" - echo " iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-text.ct >utext/dk-text.dict" - echo " iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-keyword.ct >utext/dk-keyword.dict" - echo - echo "catalogsw:" # Windows catalogs - echo " iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-help.ct >utext/dk-help.dict" - echo " iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-ident.ct >utext/dk-ident.dict" - echo " iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-text.ct >utext/dk-text.dict" - echo " iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-keyword.ct >utext/dk-keyword.dict" - echo - echo "libamathapp: ${libapp}" - echo " \${AR} rcs libamathapp${outext}.a ${libapp}" - echo " \${RANLIB} libamathapp${outext}.a" - echo - echo "libamath: ${libamath}" - echo " \${AR} rcs libamath${outext}.a ${libamath}" - echo " \${RANLIB} libamath${outext}.a" - echo - echo "libcomplex: ${libcomplex}" - echo " \${AR} rcs libcomplex${outext}.a ${libcomplex}" - echo " \${RANLIB} libcomplex${outext}.a" - echo - echo "libcamath: ${libc}" - echo " \${AR} rcs libcamath${outext}.a ${libc}" - echo " \${RANLIB} libcamath${outext}.a" - echo - echo "app: libs ${l}" - echo " \${CC} \${CFLAGS} ${ARCFLAG}${CROSSCOMPILEFLAGS}${exestrip} -L. -o amath${outext} ${l} \${LFLAGS}" - echo - echo "amigacatalogs:" - echo " \${MKDIR} dist/catalog/english" - echo " \${FLXCAT} text/help.cd catalog/english/amath-help.ct CATALOG dist/catalog/english/amath-help.catalog" - echo " \${FLXCAT} text/ident.cd catalog/english/amath-ident.ct CATALOG dist/catalog/english/amath-ident.catalog" - echo " \${FLXCAT} text/text.cd catalog/english/amath-text.ct CATALOG dist/catalog/english/amath-text.catalog" - echo " \${MKDIR} dist/catalog/dansk" - echo " \${FLXCAT} text/help.cd catalog/dansk/amath-help.ct CATALOG dist/catalog/dansk/amath-help.catalog" - echo " \${FLXCAT} text/ident.cd catalog/dansk/amath-ident.ct CATALOG dist/catalog/dansk/amath-ident.catalog" - echo " \${FLXCAT} text/text.cd catalog/dansk/amath-text.ct CATALOG dist/catalog/dansk/amath-text.catalog" - echo " \${FLXCAT} text/keyword.cd catalog/dansk/amath-keyword.ct CATALOG dist/catalog/dansk/amath-keyword.catalog" - echo - echo ".PHONY: test" - echo "test: app" - echo " ./amath test" - echo - echo ".PHONY: install" - echo "install: app" - echo " install -m 0755 amath \$(DESTDIR)\$(PREFIX)/bin" - echo - echo "clean:" - echo " \${DEL} ${libapp} ${libamath} ${libcomplex} ${libc} ${l} libamath${outext}.a libcamath${outext}.a libcomplex${outext}.a libamathapp${outext}.a amath${outext}" - echo - echo "depend:" - echo " @echo Dependencies already done" - ) > Makefile +echo ".PHONY: build" +echo "build:" +echo " \${MKDIR} static" +echo " \${MKDIR} shared" +echo +echo "\${solib}: build ${files2}" +echo " \${CC} -shared -fPIC -Wl,-soname,\${solib} -o \${solib} ${files2}" +echo +echo "\${alib}: build ${files}" +echo " \${AR} rcs static/\${alib} ${files}" +echo " \${RANLIB} static/\${alib}" +echo +echo ".PHONY: install" +echo "install: \${solib}" +echo " \${MKDIR} \${DESTDIR}\${PREFIX}/lib" +echo " \${INSTALL} \${solib} \${DESTDIR}\${PREFIX}/lib/\${solib}" +echo +echo ".PHONY: uninstall" +echo "uninstall:" +echo " \${DEL} \${DESTDIR}\${PREFIX}/lib/\${solib}" +echo +echo "clean:" +echo " \${DEL} static/\${alib} \${solib} ${files} ${files2}" +echo +} > src/lib/Makefile +######################################################################### - echo "Makefile generated${msg}" -# echo -# echo "Build with debug symbols in csh:" -# echo "DEBUG=\"Y\" make" +############################### C Library ############################### +{ +echo "CC = ${crosscompile}${ccompiler}" +echo "CFLAGS = -std=c9x ${libop}${options} ${cflags}-I. -I.. -Wall" +echo "AR = ${crosscompile}ar" +echo "RANLIB = ${crosscompile}ranlib" +echo "MKDIR = mkdir -p" +echo "DEL = rm -f" +echo "INSTALL = install -m 0644" +echo "PREFIX = ${prefix}" +echo +echo "alib = lib${amathc}.a" +echo "solib = lib${amathc}.so" +echo +echo "all: static shared" +echo +echo "static: \${alib}" +echo +echo "shared: \${solib}" +echo + +libc="" +libcs="" +for f in ${LIBC1SRCS} +do + b=`basename $f .c` + echo "static/${b}.o: ${f}" + echo " \${CC} \${CFLAGS} -fno-builtin -c ${f} -o static/${b}.o" echo -fi + echo "shared/${b}.o: ${f}" + echo " \${CC} \${CFLAGS} -fPIC -fno-builtin -c ${f} -o shared/${b}.o" + echo + libc="${libc} static/${b}.o" + libcs="${libcs} shared/${b}.o" +done + +echo ".PHONY: build" +echo "build:" +echo " \${MKDIR} static" +echo " \${MKDIR} shared" +echo +echo "\${solib}: build ${libcs}" +echo " \${CC} -shared -fPIC -Wl,-soname,\${solib} -o \${solib} ${libcs} -lc" +echo +echo "\${alib}: build ${libc}" +echo " \${AR} rcs static/\${alib} ${libc}" +echo " \${RANLIB} static/\${alib}" +echo +echo ".PHONY: install" +echo "install: \${alib} \${solib}" +echo " \${MKDIR} \${DESTDIR}\${PREFIX}/lib" +echo " \${MKDIR} \${DESTDIR}\${PREFIX}/include" +echo " \${INSTALL} static/\${alib} \${DESTDIR}\${PREFIX}/lib/\${alib}" +echo " \${INSTALL} \${solib} \${DESTDIR}\${PREFIX}/lib/\${solib}" +echo " \${INSTALL} ../amath.h \${DESTDIR}\${PREFIX}/include" +echo " \${INSTALL} ../amathc.h \${DESTDIR}\${PREFIX}/include" +echo +echo ".PHONY: uninstall" +echo "uninstall:" +echo " \${DEL} \${DESTDIR}\${PREFIX}/lib/\${alib}" +echo " \${DEL} \${DESTDIR}\${PREFIX}/lib/\${solib}" +echo " \${DEL} \${DESTDIR}\${PREFIX}/include/amath.h" +echo " \${DEL} \${DESTDIR}\${PREFIX}/include/amathc.h" +echo +echo "clean:" +echo " \${DEL} static/\${alib} \${solib} ${libc} ${libcs}" +echo +} > src/clib/Makefile + +######################################################################### + +############################# Real Numbers ############################## +{ +echo "CC = ${crosscompile}${ccompiler}" +echo "CFLAGS = -std=c9x ${libop}${options} ${cflags}-I. -I.. -Wall" +echo "AR = ${crosscompile}ar" +echo "RANLIB = ${crosscompile}ranlib" +echo "MKDIR = mkdir -p" +echo "DEL = rm -f" +echo "INSTALL = install -m 0644" +echo "PREFIX = ${prefix}" +echo +echo "alib = lib${amath}.a" +echo "solib = lib${amath}.so" +echo +echo "all: static shared" +echo +echo "static: \${alib}" +echo +echo "shared: \${solib}" +echo + +libamath="" +libamaths="" +for f in ${LIBREALSRCS} +do + b=`basename $f .c` + echo "static/${b}.o: ${f}" + echo " \${CC} \${CFLAGS} -fno-builtin -c ${f} -o static/${b}.o" + echo + echo "shared/${b}.o: ${f}" + echo " \${CC} \${CFLAGS} -fPIC -fno-builtin -c ${f} -o shared/${b}.o" + echo + libamath="${libamath} static/${b}.o" + libamaths="${libamaths} shared/${b}.o" +done + +echo ".PHONY: build" +echo "build:" +echo " \${MKDIR} static" +echo " \${MKDIR} shared" +echo +echo "\${solib}: build ${libamaths}" +echo " \${CC} -shared -fPIC -Wl,-soname,\${solib} -o \${solib} ${libamaths}" +echo +echo "\${alib}: build ${libamath}" +echo " \${AR} rcs static/\${alib} ${libamath}" +echo " \${RANLIB} static/\${alib}" +echo +echo ".PHONY: install" +echo "install: \${alib} \${solib}" +echo " \${MKDIR} \${DESTDIR}\${PREFIX}/lib" +echo " \${INSTALL} static/\${alib} \${DESTDIR}\${PREFIX}/lib/\${alib}" +echo " \${INSTALL} \${solib} \${DESTDIR}\${PREFIX}/lib/\${solib}" +echo +echo ".PHONY: uninstall" +echo "uninstall:" +echo " \${DEL} \${DESTDIR}\${PREFIX}/lib/\${alib}" +echo " \${DEL} \${DESTDIR}\${PREFIX}/lib/\${solib}" +echo +echo "clean:" +echo " \${DEL} static/\${alib} \${solib} ${libamath} ${libamaths}" +echo +} > src/real/Makefile +######################################################################### + +############################ Complex Numbers ############################ +{ +echo "CC = ${crosscompile}${ccompiler}" +echo "CFLAGS = -std=c9x ${libop}${options} ${cxxflags}-I. -I.. -Wall" +echo "AR = ${crosscompile}ar" +echo "RANLIB = ${crosscompile}ranlib" +echo "MKDIR = mkdir -p" +echo "DEL = rm -f" +echo "INSTALL = install -m 0644" +echo "PREFIX = ${prefix}" +echo +echo "alib = lib${amathcplex}.a" +echo "solib = lib${amathcplex}.so" +echo +echo "all: static shared" +echo +echo "static: \${alib}" +echo +echo "shared: \${solib}" +echo + +libcomplex="" +libcomplexs="" +for f in ${LIBCPLEXSRCS} +do + b=`basename $f .c` + echo "static/${b}.o: ${f}" + echo " \${CC} \${CFLAGS} -fno-builtin -c ${f} -o static/${b}.o" + echo + echo "shared/${b}.o: ${f}" + echo " \${CC} \${CFLAGS} -fPIC -fno-builtin -c ${f} -o shared/${b}.o" + echo + libcomplex="${libcomplex} static/${b}.o" + libcomplexs="${libcomplexs} shared/${b}.o" +done + +echo ".PHONY: build" +echo "build:" +echo " \${MKDIR} static" +echo " \${MKDIR} shared" +echo +echo "\${solib}: build ${libcomplexs}" +echo " \${CC} -shared -fPIC -Wl,-soname,\${solib} -o \${solib} ${libcomplexs}" +echo +echo "\${alib}: build ${libcomplex}" +echo " \${AR} rcs static/\${alib} ${libcomplex}" +echo " \${RANLIB} static/\${alib}" +echo +echo ".PHONY: install" +echo "install: \${alib} \${solib}" +echo " \${MKDIR} \${DESTDIR}\${PREFIX}/lib" +echo " \${INSTALL} static/\${alib} \${DESTDIR}\${PREFIX}/lib/\${alib}" +echo " \${INSTALL} \${solib} \${DESTDIR}\${PREFIX}/lib/\${solib}" +echo " \${INSTALL} ../complex.h \${DESTDIR}\${PREFIX}/include" +echo +echo ".PHONY: uninstall" +echo "uninstall:" +echo " \${DEL} \${DESTDIR}\${PREFIX}/lib/\${alib}" +echo " \${DEL} \${DESTDIR}\${PREFIX}/lib/\${solib}" +echo " \${DEL} \${DESTDIR}\${PREFIX}/include/complex.h" +echo +echo "clean:" +echo " \${DEL} static/\${alib} \${solib} ${libcomplex} ${libcomplexs}" +echo +} > src/cplex/Makefile +######################################################################### + +################################# Main ################################## +{ +echo +echo "CC = ${crosscompile}${ccompiler}" +echo "CXX = ${crosscompile}${cxxcompiler}" +echo "CFLAGS = ${appop}${options} ${cflags}-Wall -Isrc -Isrc/main" +echo "CXXFLAGS = ${appop}${options} ${cxxflags}-Wall -Isrc -Isrc/main" +echo "AR = ${crosscompile}ar" +echo "RANLIB = ${crosscompile}ranlib" +echo "LFLAGS = ${ldflags}-l${appsystem} -l${appfunction} -l${appstatement} -l${appmain} -l${appfunction} -l${appstatement} -l${appmain} -l${amathapp} -l${amathcplex} -l${amath} -l${amathc} ${gcclib}" +echo "LPATH = -Lsrc/lib -Lsrc/clib -Lsrc/real -Lsrc/cplex -Lsrc/main/function -Lsrc/main/statement -Lsrc/main -Lsrc/system" +echo "LPATHS = -Lsrc/lib/static -Lsrc/clib/static -Lsrc/real/static -Lsrc/cplex/static -Lsrc/main/function -Lsrc/main/statement -Lsrc/main -Lsrc/system" +echo "FLXCAT = build/flexcat/flexcat" +echo "MKDIR = mkdir -p" +echo "DEL = rm -f" +echo "INSTALL = install -m 0755" +echo "PREFIX = ${prefix}" +echo +echo "all: shared-app" +echo "app: ${appmain} ${appfunction} ${appstatement} ${appsystem}" +echo "libs: ${amathapp} ${amath} ${amathc} ${amathcplex}" +echo +echo "amath: static-app" +echo "static: static-app" +echo +echo "${program}.o: ${program}.cpp" +echo " \${CXX} \${CXXFLAGS} -c ${program}.cpp -o ${program}.o" +echo +echo "${appmain}:" +echo " cd src/main && \${MAKE}" +echo +echo "${appsystem}:" +echo " cd src/system && \${MAKE}" +echo +echo "${appfunction}:" +echo " cd src/main/function && \${MAKE}" +echo +echo "${appstatement}:" +echo " cd src/main/statement && \${MAKE}" +echo +echo "${amathapp}:" +echo " cd src/lib && \${MAKE}" +echo +echo "${amath}:" +echo " cd src/real && \${MAKE}" +echo +echo "${amathc}:" +echo " cd src/clib && \${MAKE}" +echo +echo "${amathcplex}:" +echo " cd src/cplex && \${MAKE}" +echo +echo "catalogsa:" # Application catalogs +echo " \${FLXCAT} text/keyword.cd src/localize/kword.h=text/keyword.sd" +echo " \${FLXCAT} text/help.cd src/localize/help.h=text/help.sd" +echo " \${FLXCAT} text/ident.cd src/localize/ident.h=text/ident.sd" +echo " \${FLXCAT} text/text.cd src/localize/text.h=text/text.sd" +echo +echo "catalogsu:" # Unix catalogs +echo " iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-help.ct >utext/dk-help.dict" +echo " iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-ident.ct >utext/dk-ident.dict" +echo " iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-text.ct >utext/dk-text.dict" +echo " iconv -f ISO-8859-15 -t UTF-8 catalog/dansk/amath-keyword.ct >utext/dk-keyword.dict" +echo +echo "catalogsw:" # Windows catalogs +echo " iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-help.ct >utext/dk-help.dict" +echo " iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-ident.ct >utext/dk-ident.dict" +echo " iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-text.ct >utext/dk-text.dict" +echo " iconv -f ISO-8859-15 -t CP850 catalog/dansk/amath-keyword.ct >utext/dk-keyword.dict" +echo +echo "amigacatalogs:" +echo " \${MKDIR} dist/catalog/english" +echo " \${FLXCAT} text/help.cd catalog/english/amath-help.ct CATALOG dist/catalog/english/amath-help.catalog" +echo " \${FLXCAT} text/ident.cd catalog/english/amath-ident.ct CATALOG dist/catalog/english/amath-ident.catalog" +echo " \${FLXCAT} text/text.cd catalog/english/amath-text.ct CATALOG dist/catalog/english/amath-text.catalog" +echo " \${MKDIR} dist/catalog/dansk" +echo " \${FLXCAT} text/help.cd catalog/dansk/amath-help.ct CATALOG dist/catalog/dansk/amath-help.catalog" +echo " \${FLXCAT} text/ident.cd catalog/dansk/amath-ident.ct CATALOG dist/catalog/dansk/amath-ident.catalog" +echo " \${FLXCAT} text/text.cd catalog/dansk/amath-text.ct CATALOG dist/catalog/dansk/amath-text.catalog" +echo " \${FLXCAT} text/keyword.cd catalog/dansk/amath-keyword.ct CATALOG dist/catalog/dansk/amath-keyword.catalog" +echo +echo "shared-app: app libs ${program}.o" +echo " \${CC} \${CFLAGS} ${exestrip} ${program}.o -o amath \${LPATH} \${LFLAGS}" +echo +echo "static-app: ${program}.o" +echo " cd src/lib && \${MAKE} static" +echo " cd src/clib && \${MAKE} static" +echo " cd src/real && \${MAKE} static" +echo " cd src/cplex && \${MAKE} static" +echo " cd src/main && \${MAKE} static" +echo " cd src/system && \${MAKE} static" +echo " cd src/main/function && \${MAKE} static" +echo " cd src/main/statement && \${MAKE} static" +echo " \${CC} \${CFLAGS} ${exestrip} ${program}.o -o amath \${LPATHS} \${LFLAGS}" +echo +echo ".PHONY: test" +echo "test: static-app" +echo " ./amath test" +echo +echo ".PHONY: install" +echo "install: amath" +echo " cd src/lib && \${MAKE} install" +echo " cd src/clib && \${MAKE} install" +echo " cd src/real && \${MAKE} install" +echo " cd src/cplex && \${MAKE} install" +echo " \${INSTALL} amath \${DESTDIR}\${PREFIX}/bin" +echo +echo ".PHONY: uninstall" +echo "uninstall:" +echo " cd src/lib && \${MAKE} uninstall" +echo " cd src/clib && \${MAKE} uninstall" +echo " cd src/real && \${MAKE} uninstall" +echo " cd src/cplex && \${MAKE} uninstall" +echo " \${DEL} \${DESTDIR}\${PREFIX}/bin/amath" +echo +echo "clean:" +echo " cd src/lib && \${MAKE} clean" +echo " cd src/clib && \${MAKE} clean" +echo " cd src/real && \${MAKE} clean" +echo " cd src/cplex && \${MAKE} clean" +echo " cd src/main && \${MAKE} clean" +echo " cd src/system && \${MAKE} clean" +echo " cd src/main/function && \${MAKE} clean" +echo " cd src/main/statement && \${MAKE} clean" +echo " \${DEL} ${program}.o amath" +echo +} > Makefile +######################################################################### +echo "Makefile generated" diff --git a/lib/dconv/dmath.cpp b/lib/dconv/dmath.cpp deleted file mode 100644 index 3ac4c51b..00000000 --- a/lib/dconv/dmath.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/****************************************************************************** - Copyright (c) 2014 Ryan Juckett - http://www.ryanjuckett.com/ - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -******************************************************************************* - Copyright (c) 2015-2017 Carsten Sonne Larsen - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The original source code can be obtained from: - http://www.ryanjuckett.com/ - -******************************************************************************/ - -#include "dstandard.h" - -//****************************************************************************** -// Get the log base 2 of a 32-bit unsigned integer. -// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogLookup -//****************************************************************************** -tU32 LogBase2( tU32 val ) -{ - static const tU8 logTable[256] = - { - 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 - }; - - tU32 temp; - - temp = val >> 24; - if (temp) - return 24 + logTable[temp]; - - temp = val >> 16; - if (temp) - return 16 + logTable[temp]; - - temp = val >> 8; - if (temp) - return 8 + logTable[temp]; - - return logTable[val]; -} diff --git a/lib/dconv/dmath.h b/lib/dconv/dmath.h deleted file mode 100644 index c5502f7c..00000000 --- a/lib/dconv/dmath.h +++ /dev/null @@ -1,84 +0,0 @@ -/****************************************************************************** - Copyright (c) 2014 Ryan Juckett - http://www.ryanjuckett.com/ - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -******************************************************************************* - Copyright (c) 2015-2017 Carsten Sonne Larsen - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The original source code can be obtained from: - http://www.ryanjuckett.com/ - -******************************************************************************/ - -#ifndef RJX_DMATH_H -#define RJX_DMATH_H - -/** - * @file dmath.h - * @brief Math used in the Dragon4 library - * - */ - -#include "dstandard.h" - -//****************************************************************************** -// Get the log base 2 of a 32-bit unsigned integer. -// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogLookup -//****************************************************************************** -tU32 LogBase2( tU32 val ); - -//****************************************************************************** -// Get the log base 2 of a 64-bit unsigned integer. -//****************************************************************************** -inline tU32 LogBase2( tU64 val ) -{ - tU64 temp; - - temp = val >> 32; - if (temp) - return 32 + LogBase2((tU32)temp); - - return LogBase2((tU32)val); -} - -#endif diff --git a/lib/dconv/dprint.cpp b/lib/dconv/dprint.cpp deleted file mode 100644 index 0cfdcd39..00000000 --- a/lib/dconv/dprint.cpp +++ /dev/null @@ -1,692 +0,0 @@ -/****************************************************************************** - Copyright (c) 2014 Ryan Juckett - http://www.ryanjuckett.com/ - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -******************************************************************************* - Copyright (c) 2015-2017 Carsten Sonne Larsen - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The original source code can be obtained from: - http://www.ryanjuckett.com/ - -******************************************************************************/ - -#include "clib.h" -#include "dmath.h" -#include "dprint.h" -#include "dragon4.h" -#include - -#define memcpy MemCopy -#define memmove MemCopy - -//****************************************************************************** -// Helper union to decompose a 32-bit IEEE float. -// sign: 1 bit -// exponent: 8 bits -// mantissa: 23 bits -//****************************************************************************** -union tFloatUnion32 -{ - tB IsNegative() const { - return (m_integer >> 31) != 0; - } - tU32 GetExponent() const { - return (m_integer >> 23) & 0xFF; - } - tU32 GetMantissa() const { - return m_integer & 0x7FFFFF; - } - - tF32 m_floatingPoint; - tU32 m_integer; -}; - -//****************************************************************************** -// Helper union to decompose a 64-bit IEEE float. -// sign: 1 bit -// exponent: 11 bits -// mantissa: 52 bits -//****************************************************************************** -union tFloatUnion64 -{ - tB IsNegative() const { - return (m_integer >> 63) != 0; - } - tU32 GetExponent() const { - return (m_integer >> 52) & 0x7FF; - } - tU64 GetMantissa() const { - return m_integer & 0xFFFFFFFFFFFFFull; - } - - tF64 m_floatingPoint; - tU64 m_integer; -}; - -//****************************************************************************** -// Outputs the positive number with positional notation: ddddd.dddd -// The output is always NUL terminated and the output length (not including the -// NUL) is returned. -//****************************************************************************** -tU32 FormatPositional -( - tC8 * pOutBuffer, // buffer to output into - tU32 bufferSize, // maximum characters that can be printed to pOutBuffer - tU64 mantissa, // value significand - tS32 exponent, // value exponent in base 2 - tU32 mantissaHighBitIdx, // index of the highest set mantissa bit - tB hasUnequalMargins, // is the high margin twice as large as the low margin - tS32 precision, // Negative prints as many digits as are needed for a unique - tC8 decimalPoint // Character before the decimals - // number. Positive specifies the maximum number of - // significant digits to print past the decimal point. -) -{ - RJ_ASSERT(bufferSize > 0); - - tS32 printExponent; - tU32 numPrintDigits; - - tU32 maxPrintLen = bufferSize - 1; - - if (precision < 0) - { - numPrintDigits = Dragon4( mantissa, - exponent, - mantissaHighBitIdx, - hasUnequalMargins, - CutoffMode_Unique, - 0, - pOutBuffer, - maxPrintLen, - &printExponent ); - } - else - { - numPrintDigits = Dragon4( mantissa, - exponent, - mantissaHighBitIdx, - hasUnequalMargins, - CutoffMode_FractionLength, - precision, - pOutBuffer, - maxPrintLen, - &printExponent ); - } - - RJ_ASSERT( numPrintDigits > 0 ); - RJ_ASSERT( numPrintDigits <= bufferSize ); - - // track the number of digits past the decimal point that have been printed - tU32 numFractionDigits = 0; - - // if output has a whole number - if (printExponent >= 0) - { - // leave the whole number at the start of the buffer - tU32 numWholeDigits = printExponent+1; - if (numPrintDigits < numWholeDigits) - { - // don't overflow the buffer - if (numWholeDigits > maxPrintLen) - numWholeDigits = maxPrintLen; - - // add trailing zeros up to the decimal point - for ( ; numPrintDigits < numWholeDigits; ++numPrintDigits ) - pOutBuffer[numPrintDigits] = '0'; - } - // insert the decimal point prior to the fraction - else if (numPrintDigits > (tU32)numWholeDigits) - { - numFractionDigits = numPrintDigits - numWholeDigits; - tU32 maxFractionDigits = maxPrintLen - numWholeDigits - 1; - if (numFractionDigits > maxFractionDigits) - numFractionDigits = maxFractionDigits; - - memmove(pOutBuffer + numWholeDigits + 1, pOutBuffer + numWholeDigits, numFractionDigits); - pOutBuffer[numWholeDigits] = decimalPoint; - numPrintDigits = numWholeDigits + 1 + numFractionDigits; - } - } - else - { - // shift out the fraction to make room for the leading zeros - if (maxPrintLen > 2) - { - tU32 numFractionZeros = (tU32)-printExponent - 1; - tU32 maxFractionZeros = maxPrintLen - 2; - if (numFractionZeros > maxFractionZeros) - numFractionZeros = maxFractionZeros; - - tU32 digitsStartIdx = 2 + numFractionZeros; - - // shift the significant digits right such that there is room for leading zeros - numFractionDigits = numPrintDigits; - tU32 maxFractionDigits = maxPrintLen - digitsStartIdx; - if (numFractionDigits > maxFractionDigits) - numFractionDigits = maxFractionDigits; - - memmove(pOutBuffer + digitsStartIdx, pOutBuffer, numFractionDigits); - - // insert the leading zeros - for (tU32 i = 2; i < digitsStartIdx; ++i) - pOutBuffer[i] = '0'; - - // update the counts - numFractionDigits += numFractionZeros; - numPrintDigits = numFractionDigits; - } - - // add the decimal point - if (maxPrintLen > 1) - { - pOutBuffer[1] = decimalPoint; - numPrintDigits += 1; - } - - // add the initial zero - if (maxPrintLen > 0) - { - pOutBuffer[0] = '0'; - numPrintDigits += 1; - } - } - - // add trailing zeros up to precision length - if (precision > (tS32)numFractionDigits && numPrintDigits < maxPrintLen) - { - // add a decimal point if this is the first fractional digit we are printing - if (numFractionDigits == 0) - { - pOutBuffer[numPrintDigits++] = decimalPoint; - } - - // compute the number of trailing zeros needed - tU32 totalDigits = numPrintDigits + (precision - numFractionDigits); - if (totalDigits > maxPrintLen) - totalDigits = maxPrintLen; - - for ( ; numPrintDigits < totalDigits; ++numPrintDigits ) - pOutBuffer[numPrintDigits] = '0'; - } - - // terminate the buffer - RJ_ASSERT( numPrintDigits <= maxPrintLen ); - pOutBuffer[numPrintDigits] = '\0'; - - return numPrintDigits; -} - -//****************************************************************************** -// Outputs the positive number with scientific notation: d.dddde[sign]ddd -// The output is always NUL terminated and the output length (not including the -// NUL) is returned. -//****************************************************************************** -tU32 FormatScientific -( - tC8 * pOutBuffer, // buffer to output into - tU32 bufferSize, // maximum characters that can be printed to pOutBuffer - tU64 mantissa, // value significand - tS32 exponent, // value exponent in base 2 - tU32 mantissaHighBitIdx, // index of the highest set mantissa bit - tB hasUnequalMargins, // is the high margin twice as large as the low margin - tS32 precision, // Negative prints as many digits as are needed for a unique - tC8 decimalPoint // Character before the decimals - // number. Positive specifies the maximum number of - // significant digits to print past the decimal point. -) -{ - RJ_ASSERT(bufferSize > 0); - - tS32 printExponent; - tU32 numPrintDigits; - - if (precision < 0) - { - numPrintDigits = Dragon4( mantissa, - exponent, - mantissaHighBitIdx, - hasUnequalMargins, - CutoffMode_Unique, - 0, - pOutBuffer, - bufferSize, - &printExponent ); - } - else - { - numPrintDigits = Dragon4( mantissa, - exponent, - mantissaHighBitIdx, - hasUnequalMargins, - CutoffMode_TotalLength, - precision + 1, - pOutBuffer, - bufferSize, - &printExponent ); - } - - RJ_ASSERT( numPrintDigits > 0 ); - RJ_ASSERT( numPrintDigits <= bufferSize ); - - tC8 * pCurOut = pOutBuffer; - - // keep the whole number as the first digit - if (bufferSize > 1) - { - pCurOut += 1; - bufferSize -= 1; - } - - // insert the decimal point prior to the fractional number - tU32 numFractionDigits = numPrintDigits-1; - if (numFractionDigits > 0 && bufferSize > 1) - { - tU32 maxFractionDigits = bufferSize-2; - if (numFractionDigits > maxFractionDigits) - numFractionDigits = maxFractionDigits; - - memmove(pCurOut + 1, pCurOut, numFractionDigits); - pCurOut[0] = decimalPoint; - pCurOut += (1 + numFractionDigits); - bufferSize -= (1 + numFractionDigits); - } - - // add trailing zeros up to precision length - if (precision > (tS32)numFractionDigits && bufferSize > 1) - { - // add a decimal point if this is the first fractional digit we are printing - if (numFractionDigits == 0) - { - *pCurOut = decimalPoint; - ++pCurOut; - --bufferSize; - } - - // compute the number of trailing zeros needed - tU32 numZeros = (precision - numFractionDigits); - if (numZeros > bufferSize-1) - numZeros = bufferSize-1; - - for (tC8 * pEnd = pCurOut + numZeros; pCurOut < pEnd; ++pCurOut ) - *pCurOut = '0'; - } - - // print the exponent into a local buffer and copy into output buffer - if (bufferSize > 1) - { - tC8 exponentBuffer[5]; - exponentBuffer[0] = 'e'; - if (printExponent >= 0) - { - exponentBuffer[1] = '+'; - } - else - { - exponentBuffer[1] = '-'; - printExponent = -printExponent; - } - - RJ_ASSERT(printExponent < 1000); - tU32 hundredsPlace = printExponent / 100; - tU32 tensPlace = (printExponent - hundredsPlace*100) / 10; - tU32 onesPlace = (printExponent - hundredsPlace*100 - tensPlace*10); - - exponentBuffer[2] = (tC8)('0' + hundredsPlace); - exponentBuffer[3] = (tC8)('0' + tensPlace); - exponentBuffer[4] = (tC8)('0' + onesPlace); - - // copy the exponent buffer into the output - tU32 maxExponentSize = bufferSize-1; - tU32 exponentSize = (5 < maxExponentSize) ? 5 : maxExponentSize; - memcpy( pCurOut, exponentBuffer, exponentSize ); - - pCurOut += exponentSize; - bufferSize -= exponentSize; - } - - RJ_ASSERT( bufferSize > 0 ); - pCurOut[0] = '\0'; - - return (tU32)(pCurOut - pOutBuffer); -} - -//****************************************************************************** -// Print a hexadecimal value with a given width. -// The output string is always NUL terminated and the string length (not -// including the NUL) is returned. -//****************************************************************************** -static tU32 PrintHex(tC8 * pOutBuffer, tU32 bufferSize, tU64 value, tU32 width) -{ - const tC8 digits[] = "0123456789abcdef"; - - RJ_ASSERT(bufferSize > 0); - - tU32 maxPrintLen = bufferSize-1; - if (width > maxPrintLen) - width = maxPrintLen; - - tC8 * pCurOut = pOutBuffer; - while (width > 0) - { - --width; - - tU8 digit = (tU8)((value >> 4ull*(tU64)width) & 0xF); - *pCurOut = digits[digit]; - - ++pCurOut; - } - - *pCurOut = '\0'; - return (tU32)(pCurOut - pOutBuffer); -} - -//****************************************************************************** -// Print special case values for infinities and NaNs. -// The output string is always NUL terminated and the string length (not -// including the NUL) is returned. -//****************************************************************************** -static tU32 PrintInfNan(tC8 * pOutBuffer, tU32 bufferSize, tU64 mantissa, tU32 mantissaHexWidth) -{ - RJ_ASSERT(bufferSize > 0); - - tU32 maxPrintLen = bufferSize-1; - - // Check for infinity - if (mantissa == 0) - { - // copy and make sure the buffer is terminated - tU32 printLen = (3 < maxPrintLen) ? 3 : maxPrintLen; - ::memcpy( pOutBuffer, "Inf", printLen ); - pOutBuffer[printLen] = '\0'; - return printLen; - } - else - { - // copy and make sure the buffer is terminated - tU32 printLen = (3 < maxPrintLen) ? 3 : maxPrintLen; - ::memcpy( pOutBuffer, "NaN", printLen ); - pOutBuffer[printLen] = '\0'; - - // append HEX value - if (maxPrintLen > 3) - printLen += PrintHex(pOutBuffer+3, bufferSize-3, mantissa, mantissaHexWidth); - - return printLen; - } -} - -//****************************************************************************** -// Print a 32-bit floating-point number as a decimal string. -// The output string is always NUL terminated and the string length (not -// including the NUL) is returned. -//****************************************************************************** -tU32 PrintFloat32 -( - tC8 * pOutBuffer, // buffer to output into - tU32 bufferSize, // size of pOutBuffer - tF32 value, // value to print - tPrintFloatFormat format, // format to print with - tS32 precision, // If negative, the minimum number of digits to represent a - tC8 decimalPoint // Character before the decimals - // unique 32-bit floating point value is output. Otherwise, - // this is the number of digits to print past the decimal point. -) -{ - if (bufferSize == 0) - return 0; - - if (bufferSize == 1) - { - pOutBuffer[0] = '\0'; - return 1; - } - - // deconstruct the floating point value - tFloatUnion32 floatUnion; - floatUnion.m_floatingPoint = value; - tU32 floatExponent = floatUnion.GetExponent(); - tU32 floatMantissa = floatUnion.GetMantissa(); - - // output the sign - if (floatUnion.IsNegative()) - { - pOutBuffer[0] = '-'; - ++pOutBuffer; - --bufferSize; - RJ_ASSERT(bufferSize > 0); - } - - // if this is a special value - if (floatExponent == 0xFF) - { - return PrintInfNan(pOutBuffer, bufferSize, floatMantissa, 6); - } - // else this is a number - else - { - // factor the value into its parts - tU32 mantissa; - tS32 exponent; - tU32 mantissaHighBitIdx; - tB hasUnequalMargins; - if (floatExponent != 0) - { - // normalized - // The floating point equation is: - // value = (1 + mantissa/2^23) * 2 ^ (exponent-127) - // We convert the integer equation by factoring a 2^23 out of the exponent - // value = (1 + mantissa/2^23) * 2^23 * 2 ^ (exponent-127-23) - // value = (2^23 + mantissa) * 2 ^ (exponent-127-23) - // Because of the implied 1 in front of the mantissa we have 24 bits of precision. - // m = (2^23 + mantissa) - // e = (exponent-127-23) - mantissa = (1UL << 23) | floatMantissa; - exponent = floatExponent - 127 - 23; - mantissaHighBitIdx = 23; - hasUnequalMargins = (floatExponent != 1) && (floatMantissa == 0); - } - else - { - // denormalized - // The floating point equation is: - // value = (mantissa/2^23) * 2 ^ (1-127) - // We convert the integer equation by factoring a 2^23 out of the exponent - // value = (mantissa/2^23) * 2^23 * 2 ^ (1-127-23) - // value = mantissa * 2 ^ (1-127-23) - // We have up to 23 bits of precision. - // m = (mantissa) - // e = (1-127-23) - mantissa = floatMantissa; - exponent = 1 - 127 - 23; - mantissaHighBitIdx = LogBase2(mantissa); - hasUnequalMargins = false; - } - - // format the value - switch (format) - { - case PrintFloatFormat_Positional: - return FormatPositional( pOutBuffer, - bufferSize, - mantissa, - exponent, - mantissaHighBitIdx, - hasUnequalMargins, - precision, - decimalPoint ); - - case PrintFloatFormat_Scientific: - return FormatScientific( pOutBuffer, - bufferSize, - mantissa, - exponent, - mantissaHighBitIdx, - hasUnequalMargins, - precision, - decimalPoint ); - - default: - pOutBuffer[0] = '\0'; - return 0; - } - } -} - -//****************************************************************************** -// Print a 64-bit floating-point number as a decimal string. -// The output string is always NUL terminated and the string length (not -// including the NUL) is returned. -//****************************************************************************** -tU32 PrintFloat64 -( - tC8 * pOutBuffer, // buffer to output into - tU32 bufferSize, // size of pOutBuffer - tF64 value, // value to print - tPrintFloatFormat format, // format to print with - tS32 precision, // If negative, the minimum number of digits to represent a - tC8 decimalPoint // Character before the decimals - // unique 64-bit floating point value is output. Otherwise, - // this is the number of digits to print past the decimal point. -) -{ - if (bufferSize == 0) - return 0; - - if (bufferSize == 1) - { - pOutBuffer[0] = '\0'; - return 1; - } - - // deconstruct the floating point value - tFloatUnion64 floatUnion; - floatUnion.m_floatingPoint = value; - tU32 floatExponent = floatUnion.GetExponent(); - tU64 floatMantissa = floatUnion.GetMantissa(); - - // output the sign - if (floatUnion.IsNegative()) - { - pOutBuffer[0] = '-'; - ++pOutBuffer; - --bufferSize; - RJ_ASSERT(bufferSize > 0); - } - - // if this is a special value - if (floatExponent == 0x7FF) - { - return PrintInfNan(pOutBuffer, bufferSize, floatMantissa, 13); - } - // else this is a number - else - { - // factor the value into its parts - tU64 mantissa; - tS32 exponent; - tU32 mantissaHighBitIdx; - tB hasUnequalMargins; - - if (floatExponent != 0) - { - // normal - // The floating point equation is: - // value = (1 + mantissa/2^52) * 2 ^ (exponent-1023) - // We convert the integer equation by factoring a 2^52 out of the exponent - // value = (1 + mantissa/2^52) * 2^52 * 2 ^ (exponent-1023-52) - // value = (2^52 + mantissa) * 2 ^ (exponent-1023-52) - // Because of the implied 1 in front of the mantissa we have 53 bits of precision. - // m = (2^52 + mantissa) - // e = (exponent-1023+1-53) - mantissa = (1ull << 52) | floatMantissa; - exponent = floatExponent - 1023 - 52; - mantissaHighBitIdx = 52; - hasUnequalMargins = (floatExponent != 1) && (floatMantissa == 0); - } - else - { - // subnormal - // The floating point equation is: - // value = (mantissa/2^52) * 2 ^ (1-1023) - // We convert the integer equation by factoring a 2^52 out of the exponent - // value = (mantissa/2^52) * 2^52 * 2 ^ (1-1023-52) - // value = mantissa * 2 ^ (1-1023-52) - // We have up to 52 bits of precision. - // m = (mantissa) - // e = (1-1023-52) - mantissa = floatMantissa; - exponent = 1 - 1023 - 52; - mantissaHighBitIdx = LogBase2(mantissa); - hasUnequalMargins = false; - } - - // format the value - switch (format) - { - case PrintFloatFormat_Positional: - return FormatPositional( pOutBuffer, - bufferSize, - mantissa, - exponent, - mantissaHighBitIdx, - hasUnequalMargins, - precision, - decimalPoint ); - - case PrintFloatFormat_Scientific: - return FormatScientific( pOutBuffer, - bufferSize, - mantissa, - exponent, - mantissaHighBitIdx, - hasUnequalMargins, - precision, - decimalPoint ); - - default: - pOutBuffer[0] = '\0'; - return 0; - } - } -} diff --git a/lib/dconv/dragon4.cpp b/lib/dconv/dragon4.cpp deleted file mode 100644 index 1367fbad..00000000 --- a/lib/dconv/dragon4.cpp +++ /dev/null @@ -1,1161 +0,0 @@ -/****************************************************************************** - Copyright (c) 2014 Ryan Juckett - http://www.ryanjuckett.com/ - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -******************************************************************************* - Copyright (c) 2015-2017 Carsten Sonne Larsen - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The original source code can be obtained from: - http://www.ryanjuckett.com/ - -******************************************************************************/ - -#include "math.h" -#include "dmath.h" -#include "dragon4.h" - -//****************************************************************************** -// Maximum number of 32 bit blocks needed in high precision arithmetic -// to print out 64 bit IEEE floating point values. -//****************************************************************************** -const tU32 c_BigInt_MaxBlocks = 35; - -//****************************************************************************** -// This structure stores a high precision unsigned integer. It uses a buffer -// of 32 bit integer blocks along with a length. The lowest bits of the integer -// are stored at the start of the buffer and the length is set to the minimum -// value that contains the integer. Thus, there are never any zero blocks at the -// end of the buffer. -//****************************************************************************** -struct tBigInt -{ - // Copy integer - tBigInt & operator=(const tBigInt &rhs) - { - tU32 length = rhs.m_length; - tU32 * pLhsCur = m_blocks; - for (const tU32 *pRhsCur = rhs.m_blocks, *pRhsEnd = pRhsCur + length; - pRhsCur != pRhsEnd; - ++pLhsCur, ++pRhsCur) - { - *pLhsCur = *pRhsCur; - } - m_length = length; - return *this; - } - - // Data accessors - tU32 GetLength() const { - return m_length; - } - tU32 GetBlock(tU32 idx) const { - return m_blocks[idx]; - } - - // Zero helper functions - void SetZero() { - m_length = 0; - } - tB IsZero() const { - return m_length == 0; - } - - // Basic type accessors - void SetU64(tU64 val) - { - if (val > 0xFFFFFFFF) - { - m_blocks[0] = val & 0xFFFFFFFF; - m_blocks[1] = (val >> 32) & 0xFFFFFFFF; - m_length = 2; - } - else if (val != 0) - { - m_blocks[0] = val & 0xFFFFFFFF; - m_length = 1; - } - else - { - m_length = 0; - } - } - - void SetU32(tU32 val) - { - if (val != 0) - { - m_blocks[0] = val; - m_length = (val != 0); - } - else - { - m_length = 0; - } - } - - tU32 GetU32() const { - return (m_length == 0) ? 0 : m_blocks[0]; - } - - // Member data - tU32 m_length; - tU32 m_blocks[c_BigInt_MaxBlocks]; -}; - -//****************************************************************************** -// Returns 0 if (lhs = rhs), negative if (lhs < rhs), positive if (lhs > rhs) -//****************************************************************************** -static tS32 BigInt_Compare(const tBigInt & lhs, const tBigInt & rhs) -{ - // A bigger length implies a bigger number. - tS32 lengthDiff = lhs.m_length - rhs.m_length; - if (lengthDiff != 0) - return lengthDiff; - - // Compare blocks one by one from high to low. - for (tS32 i = lhs.m_length - 1; i >= 0; --i) - { - if (lhs.m_blocks[i] == rhs.m_blocks[i]) - continue; - else if (lhs.m_blocks[i] > rhs.m_blocks[i]) - return 1; - else - return -1; - } - - // no blocks differed - return 0; -} - -//****************************************************************************** -// result = lhs + rhs -//****************************************************************************** -static void BigInt_Add(tBigInt * pResult, const tBigInt & lhs, const tBigInt & rhs) -{ - // determine which operand has the smaller length - const tBigInt * pLarge; - const tBigInt * pSmall; - if (lhs.m_length < rhs.m_length) - { - pSmall = &lhs; - pLarge = &rhs; - } - else - { - pSmall = &rhs; - pLarge = &lhs; - } - - const tU32 largeLen = pLarge->m_length; - const tU32 smallLen = pSmall->m_length; - - // The output will be at least as long as the largest input - pResult->m_length = largeLen; - - // Add each block and add carry the overflow to the next block - tU64 carry = 0; - const tU32 * pLargeCur = pLarge->m_blocks; - const tU32 * pLargeEnd = pLargeCur + largeLen; - const tU32 * pSmallCur = pSmall->m_blocks; - const tU32 * pSmallEnd = pSmallCur + smallLen; - tU32 * pResultCur = pResult->m_blocks; - while (pSmallCur != pSmallEnd) - { - tU64 sum = carry + (tU64)(*pLargeCur) + (tU64)(*pSmallCur); - carry = sum >> 32; - (*pResultCur) = sum & 0xFFFFFFFF; - ++pLargeCur; - ++pSmallCur; - ++pResultCur; - } - - // Add the carry to any blocks that only exist in the large operand - while (pLargeCur != pLargeEnd) - { - tU64 sum = carry + (tU64)(*pLargeCur); - carry = sum >> 32; - (*pResultCur) = sum & 0xFFFFFFFF; - ++pLargeCur; - ++pResultCur; - } - - // If there's still a carry, append a new block - if (carry != 0) - { - RJ_ASSERT(carry == 1); - RJ_ASSERT((tU32)(pResultCur - pResult->m_blocks) == largeLen && (largeLen < c_BigInt_MaxBlocks)); - *pResultCur = 1; - pResult->m_length = largeLen + 1; - } - else - { - pResult->m_length = largeLen; - } -} - -//****************************************************************************** -// result = lhs * rhs -//****************************************************************************** -static void BigInt_Multiply(tBigInt * pResult, const tBigInt &lhs, const tBigInt &rhs) -{ - RJ_ASSERT( pResult != &lhs && pResult != &rhs ); - - // determine which operand has the smaller length - const tBigInt * pLarge; - const tBigInt * pSmall; - if (lhs.m_length < rhs.m_length) - { - pSmall = &lhs; - pLarge = &rhs; - } - else - { - pSmall = &rhs; - pLarge = &lhs; - } - - // set the maximum possible result length - tU32 maxResultLen = pLarge->m_length + pSmall->m_length; - RJ_ASSERT( maxResultLen <= c_BigInt_MaxBlocks ); - - // clear the result data - for(tU32 * pCur = pResult->m_blocks, *pEnd = pCur + maxResultLen; pCur != pEnd; ++pCur) - *pCur = 0; - - // perform standard long multiplication - const tU32 *pLargeBeg = pLarge->m_blocks; - const tU32 *pLargeEnd = pLargeBeg + pLarge->m_length; - - // for each small block - tU32 *pResultStart = pResult->m_blocks; - for(const tU32 *pSmallCur = pSmall->m_blocks, *pSmallEnd = pSmallCur + pSmall->m_length; - pSmallCur != pSmallEnd; - ++pSmallCur, ++pResultStart) - { - // if non-zero, multiply against all the large blocks and add into the result - const tU32 multiplier = *pSmallCur; - if (multiplier != 0) - { - const tU32 *pLargeCur = pLargeBeg; - tU32 *pResultCur = pResultStart; - tU64 carry = 0; - do - { - tU64 product = (*pResultCur) + (*pLargeCur)*(tU64)multiplier + carry; - carry = product >> 32; - *pResultCur = product & 0xFFFFFFFF; - ++pLargeCur; - ++pResultCur; - } while(pLargeCur != pLargeEnd); - - RJ_ASSERT(pResultCur < pResult->m_blocks + maxResultLen); - *pResultCur = (tU32)(carry & 0xFFFFFFFF); - } - } - - // check if the terminating block has no set bits - if (maxResultLen > 0 && pResult->m_blocks[maxResultLen - 1] == 0) - pResult->m_length = maxResultLen-1; - else - pResult->m_length = maxResultLen; -} - -//****************************************************************************** -// result = lhs * rhs -//****************************************************************************** -static void BigInt_Multiply(tBigInt * pResult, const tBigInt & lhs, tU32 rhs) -{ - // perform long multiplication - tU32 carry = 0; - tU32 *pResultCur = pResult->m_blocks; - const tU32 *pLhsCur = lhs.m_blocks; - const tU32 *pLhsEnd = lhs.m_blocks + lhs.m_length; - for ( ; pLhsCur != pLhsEnd; ++pLhsCur, ++pResultCur ) - { - tU64 product = (tU64)(*pLhsCur) * rhs + carry; - *pResultCur = (tU32)(product & 0xFFFFFFFF); - carry = product >> 32; - } - - // if there is a remaining carry, grow the array - if (carry != 0) - { - // grow the array - RJ_ASSERT(lhs.m_length + 1 <= c_BigInt_MaxBlocks); - *pResultCur = (tU32)carry; - pResult->m_length = lhs.m_length + 1; - } - else - { - pResult->m_length = lhs.m_length; - } -} - -//****************************************************************************** -// result = in * 2 -//****************************************************************************** -static void BigInt_Multiply2(tBigInt * pResult, const tBigInt &in) -{ - // shift all the blocks by one - tU32 carry = 0; - - tU32 *pResultCur = pResult->m_blocks; - const tU32 *pLhsCur = in.m_blocks; - const tU32 *pLhsEnd = in.m_blocks + in.m_length; - for ( ; pLhsCur != pLhsEnd; ++pLhsCur, ++pResultCur ) - { - tU32 cur = *pLhsCur; - *pResultCur = (cur << 1) | carry; - carry = cur >> 31; - } - - if (carry != 0) - { - // grow the array - RJ_ASSERT(in.m_length + 1 <= c_BigInt_MaxBlocks); - *pResultCur = carry; - pResult->m_length = in.m_length + 1; - } - else - { - pResult->m_length = in.m_length; - } -} - -//****************************************************************************** -// result = result * 2 -//****************************************************************************** -static void BigInt_Multiply2(tBigInt * pResult) -{ - // shift all the blocks by one - tU32 carry = 0; - - tU32 *pCur = pResult->m_blocks; - tU32 *pEnd = pResult->m_blocks + pResult->m_length; - for ( ; pCur != pEnd; ++pCur ) - { - tU32 cur = *pCur; - *pCur = (cur << 1) | carry; - carry = cur >> 31; - } - - if (carry != 0) - { - // grow the array - RJ_ASSERT(pResult->m_length + 1 <= c_BigInt_MaxBlocks); - *pCur = carry; - ++pResult->m_length; - } -} - -//****************************************************************************** -// result = result * 10 -//****************************************************************************** -static void BigInt_Multiply10(tBigInt * pResult) -{ - // multiply all the blocks - tU64 carry = 0; - - tU32 *pCur = pResult->m_blocks; - tU32 *pEnd = pResult->m_blocks + pResult->m_length; - for ( ; pCur != pEnd; ++pCur ) - { - tU64 product = (tU64)(*pCur) * 10ull + carry; - (*pCur) = (tU32)(product & 0xFFFFFFFF); - carry = product >> 32; - } - - if (carry != 0) - { - // grow the array - RJ_ASSERT(pResult->m_length + 1 <= c_BigInt_MaxBlocks); - *pCur = (tU32)carry; - ++pResult->m_length; - } -} - -//****************************************************************************** -//****************************************************************************** -static tU32 g_PowerOf10_U32[] = -{ - 1, // 10 ^ 0 - 10, // 10 ^ 1 - 100, // 10 ^ 2 - 1000, // 10 ^ 3 - 10000, // 10 ^ 4 - 100000, // 10 ^ 5 - 1000000, // 10 ^ 6 - 10000000, // 10 ^ 7 -}; - -//****************************************************************************** -// Note: This has a lot of wasted space in the big integer structures of the -// early table entries. It wouldn't be terribly hard to make the multiply -// function work on integer pointers with an array length instead of -// the tBigInt struct which would allow us to store a minimal amount of -// data here. -//****************************************************************************** -static tBigInt g_PowerOf10_Big[] = -{ - // 10 ^ 8 - { 1, { 100000000 } }, - // 10 ^ 16 - { 2, { 0x6fc10000, 0x002386f2 } }, - // 10 ^ 32 - { 4, { 0x00000000, 0x85acef81, 0x2d6d415b, 0x000004ee, } }, - // 10 ^ 64 - { 7, { 0x00000000, 0x00000000, 0xbf6a1f01, 0x6e38ed64, 0xdaa797ed, 0xe93ff9f4, 0x00184f03, } }, - // 10 ^ 128 - { 14, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x2e953e01, 0x03df9909, 0x0f1538fd, - 0x2374e42f, 0xd3cff5ec, 0xc404dc08, 0xbccdb0da, 0xa6337f19, 0xe91f2603, 0x0000024e, - } - }, - // 10 ^ 256 - { 27, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x982e7c01, 0xbed3875b, 0xd8d99f72, 0x12152f87, 0x6bde50c6, 0xcf4a6e70, - 0xd595d80f, 0x26b2716e, 0xadc666b0, 0x1d153624, 0x3c42d35a, 0x63ff540e, 0xcc5573c0, - 0x65f9ef17, 0x55bc28f2, 0x80dcc7f7, 0xf46eeddc, 0x5fdcefce, 0x000553f7, - } - } -}; - -//****************************************************************************** -// result = 10^exponent -//****************************************************************************** -static void BigInt_Pow10(tBigInt * pResult, tU32 exponent) -{ - // make sure the exponent is within the bounds of the lookup table data - RJ_ASSERT(exponent < 512); - - // create two temporary values to reduce large integer copy operations - tBigInt temp1; - tBigInt temp2; - tBigInt *pCurTemp = &temp1; - tBigInt *pNextTemp = &temp2; - - // initialize the result by looking up a 32-bit power of 10 corresponding to the first 3 bits - tU32 smallExponent = exponent & 0x7; - pCurTemp->SetU32(g_PowerOf10_U32[smallExponent]); - - // remove the low bits that we used for the 32-bit lookup table - exponent >>= 3; - tU32 tableIdx = 0; - - // while there are remaining bits in the exponent to be processed - while (exponent != 0) - { - // if the current bit is set, multiply it with the corresponding power of 10 - if(exponent & 1) - { - // multiply into the next temporary - BigInt_Multiply( pNextTemp, *pCurTemp, g_PowerOf10_Big[tableIdx] ); - - // swap to the next temporary - tBigInt * pSwap = pCurTemp; - pCurTemp = pNextTemp; - pNextTemp = pSwap; - } - - // advance to the next bit - ++tableIdx; - exponent >>= 1; - } - - // output the result - *pResult = *pCurTemp; -} - -//****************************************************************************** -// result = in * 10^exponent -//****************************************************************************** -static void BigInt_MultiplyPow10(tBigInt * pResult, const tBigInt & in, tU32 exponent) -{ - // make sure the exponent is within the bounds of the lookup table data - RJ_ASSERT(exponent < 512); - - // create two temporary values to reduce large integer copy operations - tBigInt temp1; - tBigInt temp2; - tBigInt *pCurTemp = &temp1; - tBigInt *pNextTemp = &temp2; - - // initialize the result by looking up a 32-bit power of 10 corresponding to the first 3 bits - tU32 smallExponent = exponent & 0x7; - if (smallExponent != 0) - { - BigInt_Multiply( pCurTemp, in, g_PowerOf10_U32[smallExponent] ); - } - else - { - *pCurTemp = in; - } - - // remove the low bits that we used for the 32-bit lookup table - exponent >>= 3; - tU32 tableIdx = 0; - - // while there are remaining bits in the exponent to be processed - while (exponent != 0) - { - // if the current bit is set, multiply it with the corresponding power of 10 - if(exponent & 1) - { - // multiply into the next temporary - BigInt_Multiply( pNextTemp, *pCurTemp, g_PowerOf10_Big[tableIdx] ); - - // swap to the next temporary - tBigInt * pSwap = pCurTemp; - pCurTemp = pNextTemp; - pNextTemp = pSwap; - } - - // advance to the next bit - ++tableIdx; - exponent >>= 1; - } - - // output the result - *pResult = *pCurTemp; -} - -//****************************************************************************** -// result = 2^exponent -//****************************************************************************** -static inline void BigInt_Pow2(tBigInt * pResult, tU32 exponent) -{ - tU32 blockIdx = exponent / 32; - RJ_ASSERT( blockIdx < c_BigInt_MaxBlocks ); - - for ( tU32 i = 0; i <= blockIdx; ++i) - pResult->m_blocks[i] = 0; - - pResult->m_length = blockIdx + 1; - - tU32 bitIdx = (exponent % 32); - pResult->m_blocks[blockIdx] |= (1 << bitIdx); -} - -//****************************************************************************** -// This function will divide two large numbers under the assumption that the -// result is within the range [0,10) and the input numbers have been shifted -// to satisfy: -// - The highest block of the divisor is greater than or equal to 8 such that -// there is enough precision to make an accurate first guess at the quotient. -// - The highest block of the divisor is less than the maximum value on an -// unsigned 32-bit integer such that we can safely increment without overflow. -// - The dividend does not contain more blocks than the divisor such that we -// can estimate the quotient by dividing the equivalently placed high blocks. -// -// quotient = floor(dividend / divisor) -// remainder = dividend - quotient*divisor -// -// pDividend is updated to be the remainder and the quotient is returned. -//****************************************************************************** -static tU32 BigInt_DivideWithRemainder_MaxQuotient9(tBigInt * pDividend, const tBigInt & divisor) -{ - // Check that the divisor has been correctly shifted into range and that it is not - // smaller than the dividend in length. - RJ_ASSERT( !divisor.IsZero() && - divisor.m_blocks[divisor.m_length-1] >= 8 && - divisor.m_blocks[divisor.m_length-1] < 0xFFFFFFFF && - pDividend->m_length <= divisor.m_length ); - - // If the dividend is smaller than the divisor, the quotient is zero and the divisor is already - // the remainder. - tU32 length = divisor.m_length; - if (pDividend->m_length < divisor.m_length) - return 0; - - const tU32 * pFinalDivisorBlock = divisor.m_blocks + length - 1; - tU32 * pFinalDividendBlock = pDividend->m_blocks + length - 1; - - // Compute an estimated quotient based on the high block value. This will either match the actual quotient or - // undershoot by one. - tU32 quotient = *pFinalDividendBlock / (*pFinalDivisorBlock + 1); - RJ_ASSERT(quotient <= 9); - - // Divide out the estimated quotient - if (quotient != 0) - { - // dividend = dividend - divisor*quotient - const tU32 *pDivisorCur = divisor.m_blocks; - tU32 *pDividendCur = pDividend->m_blocks; - - tU64 borrow = 0; - tU64 carry = 0; - do - { - tU64 product = (tU64)*pDivisorCur * (tU64)quotient + carry; - carry = product >> 32; - - tU64 difference = (tU64)*pDividendCur - (product & 0xFFFFFFFF) - borrow; - borrow = (difference >> 32) & 1; - - *pDividendCur = difference & 0xFFFFFFFF; - - ++pDivisorCur; - ++pDividendCur; - } while(pDivisorCur <= pFinalDivisorBlock); - - // remove all leading zero blocks from dividend - while (length > 0 && pDividend->m_blocks[length - 1] == 0) - --length; - - pDividend->m_length = length; - } - - // If the dividend is still larger than the divisor, we overshot our estimate quotient. To correct, - // we increment the quotient and subtract one more divisor from the dividend. - if ( BigInt_Compare(*pDividend, divisor) >= 0 ) - { - ++quotient; - - // dividend = dividend - divisor - const tU32 *pDivisorCur = divisor.m_blocks; - tU32 *pDividendCur = pDividend->m_blocks; - - tU64 borrow = 0; - do - { - tU64 difference = (tU64)*pDividendCur - (tU64)*pDivisorCur - borrow; - borrow = (difference >> 32) & 1; - - *pDividendCur = difference & 0xFFFFFFFF; - - ++pDivisorCur; - ++pDividendCur; - } while(pDivisorCur <= pFinalDivisorBlock); - - // remove all leading zero blocks from dividend - while (length > 0 && pDividend->m_blocks[length - 1] == 0) - --length; - - pDividend->m_length = length; - } - - return quotient; -} - -//****************************************************************************** -// result = result << shift -//****************************************************************************** -static void BigInt_ShiftLeft(tBigInt * pResult, tU32 shift) -{ - RJ_ASSERT( shift != 0 ); - - tU32 shiftBlocks = shift / 32; - tU32 shiftBits = shift % 32; - - // process blocks high to low so that we can safely process in place - const tU32 * pInBlocks = pResult->m_blocks; - tS32 inLength = pResult->m_length; - RJ_ASSERT( inLength + shiftBlocks < c_BigInt_MaxBlocks ); - - // check if the shift is block aligned - if (shiftBits == 0) - { - // copy blcoks from high to low - for (tU32 * pInCur = pResult->m_blocks + inLength, *pOutCur = pInCur + shiftBlocks; - pInCur >= pInBlocks; - --pInCur, --pOutCur) - { - *pOutCur = *pInCur; - } - - // zero the remaining low blocks - for ( tU32 i = 0; i < shiftBlocks; ++i) - pResult->m_blocks[i] = 0; - - pResult->m_length += shiftBlocks; - } - // else we need to shift partial blocks - else - { - tS32 inBlockIdx = inLength - 1; - tU32 outBlockIdx = inLength + shiftBlocks; - - // set the length to hold the shifted blocks - RJ_ASSERT( outBlockIdx < c_BigInt_MaxBlocks ); - pResult->m_length = outBlockIdx + 1; - - // output the initial blocks - const tU32 lowBitsShift = (32 - shiftBits); - tU32 highBits = 0; - tU32 block = pResult->m_blocks[inBlockIdx]; - tU32 lowBits = block >> lowBitsShift; - while ( inBlockIdx > 0 ) - { - pResult->m_blocks[outBlockIdx] = highBits | lowBits; - highBits = block << shiftBits; - - --inBlockIdx; - --outBlockIdx; - - block = pResult->m_blocks[inBlockIdx]; - lowBits = block >> lowBitsShift; - } - - // output the final blocks - RJ_ASSERT( outBlockIdx == shiftBlocks + 1 ); - pResult->m_blocks[outBlockIdx] = highBits | lowBits; - pResult->m_blocks[outBlockIdx-1] = block << shiftBits; - - // zero the remaining low blocks - for ( tU32 i = 0; i < shiftBlocks; ++i) - pResult->m_blocks[i] = 0; - - // check if the terminating block has no set bits - if (pResult->m_blocks[pResult->m_length - 1] == 0) - --pResult->m_length; - } -} - -//****************************************************************************** -// This is an implementation the Dragon4 algorithm to convert a binary number -// in floating point format to a decimal number in string format. The function -// returns the number of digits written to the output buffer and the output is -// not NUL terminated. -// -// The floating point input value is (mantissa * 2^exponent). -// -// See the following papers for more information on the algorithm: -// "How to Print Floating-Point Numbers Accurately" -// Steele and White -// http://kurtstephens.com/files/p372-steele.pdf -// "Printing Floating-Point Numbers Quickly and Accurately" -// Burger and Dybvig -// http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.4656&rep=rep1&type=pdf -//****************************************************************************** -tU32 Dragon4 -( - const tU64 mantissa, // value significand - const tS32 exponent, // value exponent in base 2 - const tU32 mantissaHighBitIdx, // index of the highest set mantissa bit - const tB hasUnequalMargins, // is the high margin twice as large as the low margin - const tCutoffMode cutoffMode, // how to determine output length - tU32 cutoffNumber, // parameter to the selected cutoffMode - tC8 * pOutBuffer, // buffer to output into - tU32 bufferSize, // maximum characters that can be printed to pOutBuffer - tS32 * pOutExponent // the base 10 exponent of the first digit -) -{ - tC8 * pCurDigit = pOutBuffer; - - RJ_ASSERT( bufferSize > 0 ); - - // if the mantissa is zero, the value is zero regardless of the exponent - if (mantissa == 0) - { - *pCurDigit = '0'; - *pOutExponent = 0; - return 1; - } - - // compute the initial state in integral form such that - // value = scaledValue / scale - // marginLow = scaledMarginLow / scale - tBigInt scale; // positive scale applied to value and margin such that they can be - // represented as whole numbers - tBigInt scaledValue; // scale * mantissa - tBigInt scaledMarginLow; // scale * 0.5 * (distance between this floating-point number and its - // immediate lower value) - - // For normalized IEEE floating point values, each time the exponent is incremented the margin also - // doubles. That creates a subset of transition numbers where the high margin is twice the size of - // the low margin. - tBigInt * pScaledMarginHigh; - tBigInt optionalMarginHigh; - - if ( hasUnequalMargins ) - { - // if we have no fractional component - if (exponent > 0) - { - // 1) Expand the input value by multiplying out the mantissa and exponent. This represents - // the input value in its whole number representation. - // 2) Apply an additional scale of 2 such that later comparisons against the margin values - // are simplified. - // 3) Set the margin value to the lowest mantissa bit's scale. - - // scaledValue = 2 * 2 * mantissa*2^exponent - scaledValue.SetU64( 4 * mantissa ); - BigInt_ShiftLeft( &scaledValue, exponent ); - - // scale = 2 * 2 * 1 - scale.SetU32( 4 ); - - // scaledMarginLow = 2 * 2^(exponent-1) - BigInt_Pow2( &scaledMarginLow, exponent ); - - // scaledMarginHigh = 2 * 2 * 2^(exponent-1) - BigInt_Pow2( &optionalMarginHigh, exponent + 1 ); - } - // else we have a fractional exponent - else - { - // In order to track the mantissa data as an integer, we store it as is with a large scale - - // scaledValue = 2 * 2 * mantissa - scaledValue.SetU64( 4 * mantissa ); - - // scale = 2 * 2 * 2^(-exponent) - BigInt_Pow2(&scale, -exponent + 2 ); - - // scaledMarginLow = 2 * 2^(-1) - scaledMarginLow.SetU32( 1 ); - - // scaledMarginHigh = 2 * 2 * 2^(-1) - optionalMarginHigh.SetU32( 2 ); - } - - // the high and low margins are different - pScaledMarginHigh = &optionalMarginHigh; - } - else - { - // if we have no fractional component - if (exponent > 0) - { - // 1) Expand the input value by multiplying out the mantissa and exponent. This represents - // the input value in its whole number representation. - // 2) Apply an additional scale of 2 such that later comparisons against the margin values - // are simplified. - // 3) Set the margin value to the lowest mantissa bit's scale. - - // scaledValue = 2 * mantissa*2^exponent - scaledValue.SetU64( 2 * mantissa ); - BigInt_ShiftLeft( &scaledValue, exponent ); - - // scale = 2 * 1 - scale.SetU32( 2 ); - - // scaledMarginLow = 2 * 2^(exponent-1) - BigInt_Pow2( &scaledMarginLow, exponent ); - } - // else we have a fractional exponent - else - { - // In order to track the mantissa data as an integer, we store it as is with a large scale - - // scaledValue = 2 * mantissa - scaledValue.SetU64( 2 * mantissa ); - - // scale = 2 * 2^(-exponent) - BigInt_Pow2(&scale, -exponent + 1 ); - - // scaledMarginLow = 2 * 2^(-1) - scaledMarginLow.SetU32( 1 ); - } - - // the high and low margins are equal - pScaledMarginHigh = &scaledMarginLow; - } - - // Compute an estimate for digitExponent that will be correct or undershoot by one. - // This optimization is based on the paper "Printing Floating-Point Numbers Quickly and Accurately" - // by Burger and Dybvig http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.4656&rep=rep1&type=pdf - // We perform an additional subtraction of 0.69 to increase the frequency of a failed estimate - // because that lets us take a faster branch in the code. 0.69 is chosen because 0.69 + log10(2) is - // less than one by a reasonable epsilon that will account for any floating point error. - // - // We want to set digitExponent to floor(log10(v)) + 1 - // v = mantissa*2^exponent - // log2(v) = log2(mantissa) + exponent; - // log10(v) = log2(v) * log10(2) - // floor(log2(v)) = mantissaHighBitIdx + exponent; - // log10(v) - log10(2) < (mantissaHighBitIdx + exponent) * log10(2) <= log10(v) - // log10(v) < (mantissaHighBitIdx + exponent) * log10(2) + log10(2) <= log10(v) + log10(2) - // floor( log10(v) ) < ceil( (mantissaHighBitIdx + exponent) * log10(2) ) <= floor( log10(v) ) + 1 - const tF64 log10_2 = 0.30102999566398119521373889472449; - tS32 digitExponent = (tS32)(ceil(tF64((tS32)mantissaHighBitIdx + exponent) * log10_2 - 0.69)); - - // if the digit exponent is smaller than the smallest desired digit for fractional cutoff, - // pull the digit back into legal range at which point we will round to the appropriate value. - // Note that while our value for digitExponent is still an estimate, this is safe because it - // only increases the number. This will either correct digitExponent to an accurate value or it - // will clamp it above the accurate value. - if (cutoffMode == CutoffMode_FractionLength && digitExponent <= -(tS32)cutoffNumber) - { - digitExponent = -(tS32)cutoffNumber + 1; - } - - // Divide value by 10^digitExponent. - if (digitExponent > 0) - { - // The exponent is positive creating a division so we multiply up the scale. - tBigInt temp; - BigInt_MultiplyPow10( &temp, scale, digitExponent ); - scale = temp; - } - else if (digitExponent < 0) - { - // The exponent is negative creating a multiplication so we multiply up the scaledValue, - // scaledMarginLow and scaledMarginHigh. - tBigInt pow10; - BigInt_Pow10( &pow10, -digitExponent); - - tBigInt temp; - BigInt_Multiply( &temp, scaledValue, pow10); - scaledValue = temp; - - BigInt_Multiply( &temp, scaledMarginLow, pow10); - scaledMarginLow = temp; - - if (pScaledMarginHigh != &scaledMarginLow) - BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow ); - } - - // If (value + marginHigh) >= 1, our estimate for digitExponent was too low - tBigInt scaledValueHigh; - BigInt_Add( &scaledValueHigh, scaledValue, *pScaledMarginHigh ); - if( BigInt_Compare(scaledValueHigh,scale) >= 0 ) - { - // The exponent estimate was incorrect. - // Increment the exponent and don't perform the premultiply needed - // for the first loop iteration. - digitExponent = digitExponent + 1; - } - else - { - // The exponent estimate was correct. - // Multiply larger by the output base to prepare for the first loop iteration. - BigInt_Multiply10( &scaledValue ); - BigInt_Multiply10( &scaledMarginLow ); - if (pScaledMarginHigh != &scaledMarginLow) - BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow ); - } - - // Compute the cutoff exponent (the exponent of the final digit to print). - // Default to the maximum size of the output buffer. - tS32 cutoffExponent = digitExponent - bufferSize; - switch(cutoffMode) - { - // print digits until we pass the accuracy margin limits or buffer size - case CutoffMode_Unique: - break; - - // print cutoffNumber of digits or until we reach the buffer size - case CutoffMode_TotalLength: - { - tS32 desiredCutoffExponent = digitExponent - (tS32)cutoffNumber; - if (desiredCutoffExponent > cutoffExponent) - cutoffExponent = desiredCutoffExponent; - } - break; - - // print cutoffNumber digits past the decimal point or until we reach the buffer size - case CutoffMode_FractionLength: - { - tS32 desiredCutoffExponent = -(tS32)cutoffNumber; - if (desiredCutoffExponent > cutoffExponent) - cutoffExponent = desiredCutoffExponent; - } - break; - } - - // Output the exponent of the first digit we will print - *pOutExponent = digitExponent-1; - - // In preparation for calling BigInt_DivideWithRemainder_MaxQuotient9(), - // we need to scale up our values such that the highest block of the denominator - // is greater than or equal to 8. We also need to guarantee that the numerator - // can never have a length greater than the denominator after each loop iteration. - // This requires the highest block of the denominator to be less than or equal to - // 429496729 which is the highest number that can be multiplied by 10 without - // overflowing to a new block. - RJ_ASSERT( scale.GetLength() > 0 ); - tU32 hiBlock = scale.GetBlock( scale.GetLength() - 1 ); - if (hiBlock < 8 || hiBlock > 429496729) - { - // Perform a bit shift on all values to get the highest block of the denominator into - // the range [8,429496729]. We are more likely to make accurate quotient estimations - // in BigInt_DivideWithRemainder_MaxQuotient9() with higher denominator values so - // we shift the denominator to place the highest bit at index 27 of the highest block. - // This is safe because (2^28 - 1) = 268435455 which is less than 429496729. This means - // that all values with a highest bit at index 27 are within range. - tU32 hiBlockLog2 = LogBase2(hiBlock); - RJ_ASSERT(hiBlockLog2 < 3 || hiBlockLog2 > 27); - tU32 shift = (32 + 27 - hiBlockLog2) % 32; - - BigInt_ShiftLeft( &scale, shift ); - BigInt_ShiftLeft( &scaledValue, shift); - BigInt_ShiftLeft( &scaledMarginLow, shift); - if (pScaledMarginHigh != &scaledMarginLow) - BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow ); - } - - // These values are used to inspect why the print loop terminated so we can properly - // round the final digit. - tB low; // did the value get within marginLow distance from zero - tB high; // did the value get within marginHigh distance from one - tU32 outputDigit; // current digit being output - - if (cutoffMode == CutoffMode_Unique) - { - // For the unique cutoff mode, we will try to print until we have reached a level of - // precision that uniquely distinguishes this value from its neighbors. If we run - // out of space in the output buffer, we terminate early. - for (;;) - { - digitExponent = digitExponent-1; - - // divide out the scale to extract the digit - outputDigit = BigInt_DivideWithRemainder_MaxQuotient9(&scaledValue, scale); - RJ_ASSERT( outputDigit < 10 ); - - // update the high end of the value - BigInt_Add( &scaledValueHigh, scaledValue, *pScaledMarginHigh ); - - // stop looping if we are far enough away from our neighboring values - // or if we have reached the cutoff digit - low = BigInt_Compare(scaledValue, scaledMarginLow) < 0; - high = BigInt_Compare(scaledValueHigh, scale) > 0; - if (low | high | (digitExponent == cutoffExponent)) - break; - - // store the output digit - *pCurDigit = (tC8)('0' + outputDigit); - ++pCurDigit; - - // multiply larger by the output base - BigInt_Multiply10( &scaledValue ); - BigInt_Multiply10( &scaledMarginLow ); - if (pScaledMarginHigh != &scaledMarginLow) - BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow ); - } - } - else - { - // For length based cutoff modes, we will try to print until we - // have exhausted all precision (i.e. all remaining digits are zeros) or - // until we reach the desired cutoff digit. - low = false; - high = false; - - for (;;) - { - digitExponent = digitExponent-1; - - // divide out the scale to extract the digit - outputDigit = BigInt_DivideWithRemainder_MaxQuotient9(&scaledValue, scale); - RJ_ASSERT( outputDigit < 10 ); - - if ( scaledValue.IsZero() | (digitExponent == cutoffExponent) ) - break; - - // store the output digit - *pCurDigit = (tC8)('0' + outputDigit); - ++pCurDigit; - - // multiply larger by the output base - BigInt_Multiply10(&scaledValue); - } - } - - // round off the final digit - // default to rounding down if value got too close to 0 - tB roundDown = low; - - // if it is legal to round up and down - if (low == high) - { - // round to the closest digit by comparing value with 0.5. To do this we need to convert - // the inequality to large integer values. - // compare( value, 0.5 ) - // compare( scale * value, scale * 0.5 ) - // compare( 2 * scale * value, scale ) - BigInt_Multiply2(&scaledValue); - tS32 compare = BigInt_Compare(scaledValue, scale); - roundDown = compare < 0; - - // if we are directly in the middle, round towards the even digit (i.e. IEEE rouding rules) - if (compare == 0) - roundDown = (outputDigit & 1) == 0; - } - - // print the rounded digit - if (roundDown) - { - *pCurDigit = (tC8)('0' + outputDigit); - ++pCurDigit; - } - else - { - // handle rounding up - if (outputDigit == 9) - { - // find the first non-nine prior digit - for (;;) - { - // if we are at the first digit - if (pCurDigit == pOutBuffer) - { - // output 1 at the next highest exponent - *pCurDigit = '1'; - ++pCurDigit; - *pOutExponent += 1; - break; - } - - --pCurDigit; - if (*pCurDigit != '9') - { - // increment the digit - *pCurDigit += 1; - ++pCurDigit; - break; - } - } - } - else - { - // values in the range [0,8] can perform a simple round up - *pCurDigit = (tC8)('0' + outputDigit + 1); - ++pCurDigit; - } - } - - // return the number of digits output - RJ_ASSERT(pCurDigit - pOutBuffer <= (tPtrDiff)bufferSize); - return (tU32)(pCurDigit - pOutBuffer); -} diff --git a/lib/dconv/dragon4.h b/lib/dconv/dragon4.h deleted file mode 100644 index 12e76118..00000000 --- a/lib/dconv/dragon4.h +++ /dev/null @@ -1,134 +0,0 @@ -/****************************************************************************** - Copyright (c) 2014 Ryan Juckett - http://www.ryanjuckett.com/ - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -******************************************************************************* - Copyright (c) 2015-2017 Carsten Sonne Larsen - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The original source code can be obtained from: - http://www.ryanjuckett.com/ - -******************************************************************************/ - -#ifndef RJX_DRAGON4_H -#define RJX_DRAGON4_H - -/** - * @file dragon4.h - * @brief Convert floating point format to a decimal number in string format. - * - * This is an implementation the Dragon4 algorithm to convert a binary number - * in floating point format to a decimal number in string format. The function - * returns the number of digits written to the output buffer and the output is - * not NUL terminated. - * - * Downloaded from:
- * http://www.ryanjuckett.com/ - * - */ - -#include "dstandard.h" - -//****************************************************************************** -// Different modes for terminating digit output -//****************************************************************************** -enum tCutoffMode -{ - CutoffMode_Unique, // as many digits as necessary to print a uniquely identifiable number - CutoffMode_TotalLength, // up to cutoffNumber significant digits - CutoffMode_FractionLength, // up to cutoffNumber significant digits past the decimal point -}; - -//****************************************************************************** -// This is an implementation the Dragon4 algorithm to convert a binary number -// in floating point format to a decimal number in string format. The function -// returns the number of digits written to the output buffer and the output is -// not NUL terminated. -// -// The floating point input value is (mantissa * 2^exponent). -// -// See the following papers for more information on the algorithm: -// "How to Print Floating-Point Numbers Accurately" -// Steele and White -// http://kurtstephens.com/files/p372-steele.pdf -// "Printing Floating-Point Numbers Quickly and Accurately" -// Burger and Dybvig -// http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.4656&rep=rep1&type=pdf -//****************************************************************************** - -/** - * @brief Dragon4 main. - * @details - * Downloaded from:
- * http://www.ryanjuckett.com/ - * - * This is an implementation the Dragon4 algorithm to convert a binary number - * in floating point format to a decimal number in string format. The function - * returns the number of digits written to the output buffer and the output is - * not NUL terminated. - * - * The floating point input value is (mantissa * 2^exponent). - * - * See the following papers for more information on the algorithm:
- * "How to Print Floating-Point Numbers Accurately"
- * Steele and White
- * http://kurtstephens.com/files/p372-steele.pdf
- * "Printing Floating-Point Numbers Quickly and Accurately"
- * Burger and Dybvig
- * http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.4656&rep=rep1&type=pdf
- * - */ -tU32 Dragon4 -( - tU64 mantissa, // value significand - tS32 exponent, // value exponent in base 2 - tU32 mantissaHighBitIdx, // index of the highest set mantissa bit - tB hasUnequalMargins, // is the high margin twice as large as the low margin - enum tCutoffMode cutoffMode, // how to determine output length - tU32 cutoffNumber, // parameter to the selected cutoffMode - tC8 * pOutBuffer, // buffer to output into - tU32 bufferSize, // maximum characters that can be printed to pOutBuffer - tS32 * pOutExponent // the base 10 exponent of the first digit -); - -#endif diff --git a/lib/dprint.h b/lib/dprint.h deleted file mode 100644 index faf737c4..00000000 --- a/lib/dprint.h +++ /dev/null @@ -1,115 +0,0 @@ -/****************************************************************************** - Copyright (c) 2014 Ryan Juckett - http://www.ryanjuckett.com/ - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -******************************************************************************* - Copyright (c) 2015-2017 Carsten Sonne Larsen - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The original source code can be obtained from: - http://www.ryanjuckett.com/ - -******************************************************************************/ - -#ifndef RJX_DPRINT_H -#define RJX_DPRINT_H - -/** - * @file dprint.h - * @brief Format defitions used in the Dragon4 library - * - */ - -#include "dstandard.h" - -#ifdef __cplusplus -extern "C" { -#endif - -//****************************************************************************** -//****************************************************************************** -enum tPrintFloatFormat -{ - PrintFloatFormat_Positional, // [-]ddddd.dddd - PrintFloatFormat_Scientific, // [-]d.dddde[sign]ddd -}; - -//****************************************************************************** -// Print a 32-bit floating-point number as a decimal string. -// The output string is always NUL terminated and the string length (not -// including the NUL) is returned. -//****************************************************************************** -tU32 PrintFloat32 -( - tC8 * pOutBuffer, // buffer to output into - tU32 bufferSize, // size of pOutBuffer - tF32 value, // value to print - tPrintFloatFormat format, // format to print with - tS32 precision, // If negative, the minimum number of digits to represent a - tC8 decimalPoint // Character before the decimals - // unique 32-bit floating point value is output. Otherwise, - // this is the number of digits to print past the decimal point. -); - -//****************************************************************************** -// Print a 64-bit floating-point number as a decimal string. -// The output string is always NUL terminated and the string length (not -// including the NUL) is returned. -//****************************************************************************** -tU32 PrintFloat64 -( - tC8 * pOutBuffer, // buffer to output into - tU32 bufferSize, // size of pOutBuffer - tF64 value, // value to print - tPrintFloatFormat format, // format to print with - tS32 precision, // If negative, the minimum number of digits to represent a - tC8 decimalPoint // Character before the decimals - // unique 64-bit floating point value is output. Otherwise, - // this is the number of digits to print past the decimal point. -); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/lib/dstandard.h b/lib/dstandard.h deleted file mode 100644 index fff7c6e5..00000000 --- a/lib/dstandard.h +++ /dev/null @@ -1,99 +0,0 @@ -/****************************************************************************** - Copyright (c) 2014 Ryan Juckett - http://www.ryanjuckett.com/ - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - - 3. This notice may not be removed or altered from any source - distribution. -******************************************************************************* - Copyright (c) 2015-2017 Carsten Sonne Larsen - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - The original source code can be obtained from: - http://www.ryanjuckett.com/ - -******************************************************************************/ - -#ifndef RJX_DSTANDARD_H -#define RJX_DSTANDARD_H - -/** - * @file dstandard.h - * @brief Type defitions for the Dragon4 library - * - */ - -#include "clib.h" -#define RJ_ASSERT(condition) - -#ifdef __cplusplus -extern "C" { -#endif - -// Boolean types -typedef bool tB; - -// Character types -typedef char tC8; - -// Unsigned integer types -typedef uint8_t tU8; -typedef uint16_t tU16; -typedef uint32_t tU32; -typedef uint64_t tU64; - -// Signed integer types -typedef int8_t tS8; -typedef int16_t tS16; -typedef int32_t tS32; -typedef int64_t tS64; - -// Floating point types -typedef float tF32; -typedef double tF64; - -// Size types -typedef size_t tSize; -typedef ptrdiff_t tPtrDiff; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/scan-build/index.html b/scan-build/index.html deleted file mode 100644 index 61326006..00000000 --- a/scan-build/index.html +++ /dev/null @@ -1,149 +0,0 @@ - - -amath - scan-build results - - - - - - -

amath - scan-build results

- - - - - - - -
User:carsten@kingster
Working Directory:/home/carsten/amath
Command Line:make
Clang Version:clang version 3.8.0-2ubuntu4 (tags/RELEASE_380/final) -
Date:Sat Jan 28 22:08:32 2017
-

Bug Summary

- - - - - - - - -
Bug TypeQuantityDisplay?
All Bugs18
Dead store
Dead assignment3
Dead increment1
Logic error
Assigned value is garbage or undefined6
Result of operation is garbage or undefined8
-

Reports

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Bug GroupBug Type ▾FileFunction/MethodLinePath Length
Logic errorAssigned value is garbage or undefinedreal/kremp2.c__kernel_rem_pio234625View Report
Logic errorAssigned value is garbage or undefinedreal/kremp2.c__kernel_rem_pio234727View Report
Logic errorAssigned value is garbage or undefinedreal/kremp2.c__kernel_rem_pio227133View Report
Logic errorAssigned value is garbage or undefinedreal/kremp2.c__kernel_rem_pio235144View Report
Logic errorAssigned value is garbage or undefinedreal/kremp2.c__kernel_rem_pio235041View Report
Logic errorAssigned value is garbage or undefineddconv/dragon4.cppBigInt_ShiftLeft70224View Report
Dead storeDead assignmentreal/expm1.cexpm11661View Report
Dead storeDead assignmentreal/expm1.cexpm11671View Report
Dead storeDead assignmentreal/pow.cpow1481View Report
Dead storeDead incrementdconv/dprint.cppFormatScientific3851View Report
Logic errorResult of operation is garbage or undefinedreal/kremp2.c__kernel_rem_pio230720View Report
Logic errorResult of operation is garbage or undefineddconv/dragon4.cppBigInt_DivideWithRemainder_MaxQuotient963138View Report
Logic errorResult of operation is garbage or undefinedreal/remp2.crempio220215View Report
Logic errorResult of operation is garbage or undefinedreal/kremp2.c__kernel_rem_pio228933View Report
Logic errorResult of operation is garbage or undefineddconv/dragon4.cppBigInt_DivideWithRemainder_MaxQuotient966039View Report
Logic errorResult of operation is garbage or undefineddconv/dragon4.cppBigInt_Multiply1040342View Report
Logic errorResult of operation is garbage or undefinedreal/kremp2.c__kernel_rem_pio222223View Report
Logic errorResult of operation is garbage or undefinedreal/kremp2.c__kernel_rem_pio232923View Report
- - diff --git a/scan-build/report-020199.html b/scan-build/report-020199.html deleted file mode 100644 index ed7dfb1d..00000000 --- a/scan-build/report-020199.html +++ /dev/null @@ -1,477 +0,0 @@ - - - -lib/real/kremp2.c - - - - - - - - - - - - - - - - - - - - - - - - - -

Bug Summary

- - - - -
File:real/kremp2.c
Location:line 289, column 21
Description:The left operand of '==' is a garbage value
- -

Annotated Source Code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/* @(#)k_rem_pio2.c 1.3 95/01/18 */
2
3/*
4 * Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * The origin source code can be obtained from:
28 * http://www.netlib.org/fdlibm/k_rem_pio2.c
29 *
30 */
31
32/*
33 * ====================================================
34 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
35 *
36 * Developed at SunSoft, a Sun Microsystems, Inc. business.
37 * Permission to use, copy, modify, and distribute this
38 * software is freely granted, provided that this notice
39 * is preserved.
40 * ====================================================
41 */
42
43#include "prim.h"
44#include "math.h"
45
46/*
47 * Constants:
48 * The hexadecimal values are the intended ones for the following
49 * constants. The decimal values may be used, provided that the
50 * compiler will convert from decimal to binary accurately enough
51 * to produce the hexadecimal values shown.
52 */
53
54static const int init_jk[] = {2,3,4,6}; /* initial value for jk */
55
56static const double PIo2[] = {
57 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
58 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
59 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
60 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
61 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
62 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
63 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
64 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
65};
66
67static const double
68zero = 0.0,
69one = 1.0,
70two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
71twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
72
73/**
74 * @brief Kernel reduction function.
75 * @version 1.4
76 * @date 96/03/07
77 * @details
78 * <pre>
79 * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
80 * double x[],y[]; int e0,nx,prec; int ipio2[];
81 *
82 * __kernel_rem_pio2 return the last three digits of N with
83 * y = x - N*pi/2
84 * so that |y| < pi/2.
85 *
86 * The method is to compute the integer (mod 8) and fraction parts of
87 * (2/pi)*x without doing the full multiplication. In general we
88 * skip the part of the product that are known to be a huge integer (
89 * more accurately, = 0 mod 8 ). Thus the number of operations are
90 * independent of the exponent of the input.
91 *
92 * (2/pi) is represented by an array of 24-bit integers in ipio2[].
93 *
94 * Input parameters:
95 * x[] The input value (must be positive) is broken into nx
96 * pieces of 24-bit integers in double precision format.
97 * x[i] will be the i-th 24 bit of x. The scaled exponent
98 * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
99 * match x's up to 24 bits.
100 *
101 * Example of breaking a double positive z into x[0]+x[1]+x[2]:
102 * e0 = ilogb(z)-23
103 * z = scalbn(z,-e0)
104 * for i = 0,1,2
105 * x[i] = floor(z)
106 * z = (z-x[i])*2**24
107 *
108 *
109 * y[] ouput result in an array of double precision numbers.
110 * The dimension of y[] is:
111 * 24-bit precision 1
112 * 53-bit precision 2
113 * 64-bit precision 2
114 * 113-bit precision 3
115 * The actual value is the sum of them. Thus for 113-bit
116 * precison, one may have to do something like:
117 *
118 * long double t,w,r_head, r_tail;
119 * t = (long double)y[2] + (long double)y[1];
120 * w = (long double)y[0];
121 * r_head = t+w;
122 * r_tail = w - (r_head - t);
123 *
124 * e0 The exponent of x[0]
125 *
126 * nx dimension of x[]
127 *
128 * prec an integer indicating the precision:
129 * 0 24 bits (single)
130 * 1 53 bits (double)
131 * 2 64 bits (extended)
132 * 3 113 bits (quad)
133 *
134 * ipio2[]
135 * integer array, contains the (24*i)-th to (24*i+23)-th
136 * bit of 2/pi after binary point. The corresponding
137 * floating value is
138 *
139 * ipio2[i] * 2^(-24(i+1)).
140 *
141 * External function:
142 * double scalbn(), floor();
143 *
144 *
145 * Here is the description of some local variables:
146 *
147 * jk jk+1 is the initial number of terms of ipio2[] needed
148 * in the computation. The recommended value is 2,3,4,
149 * 6 for single, double, extended,and quad.
150 *
151 * jz local integer variable indicating the number of
152 * terms of ipio2[] used.
153 *
154 * jx nx - 1
155 *
156 * jv index for pointing to the suitable ipio2[] for the
157 * computation. In general, we want
158 * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
159 * is an integer. Thus
160 * e0-3-24*jv >= 0 or (e0-3)/24 >= jv
161 * Hence jv = max(0,(e0-3)/24).
162 *
163 * jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
164 *
165 * q[] double array with integral value, representing the
166 * 24-bits chunk of the product of x and 2/pi.
167 *
168 * q0 the corresponding exponent of q[0]. Note that the
169 * exponent for q[i] would be q0-24*i.
170 *
171 * PIo2[] double precision array, obtained by cutting pi/2
172 * into 24 bits chunks.
173 *
174 * f[] ipio2[] in floating point
175 *
176 * iq[] integer array by breaking up q[] in 24-bits chunk.
177 *
178 * fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
179 *
180 * ih integer. If >0 it indicates q[] is >= 0.5, hence
181 * it also indicates the *sign* of the result.
182 *
183 * </pre>
184 * @copyright Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
185 * @license Developed at SunSoft, a Sun Microsystems, Inc. business. Permission
186 * to use, copy, modify, and distribute this software is freely granted,
187 * provided that this notice is preserved.
188 */
189
190int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int *ipio2)
191{
192 int jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
193 double z,fw,f[20],fq[20],q[20];
194
195 /* initialize jk*/
196 jk = init_jk[prec];
197 jp = jk;
198
199 /* determine jx,jv,q0, note that 3>q0 */
200 jx = nx-1;
201 jv = (e0-3)/24;
202 if(jv<0) jv=0;
1
Assuming 'jv' is >= 0
2
Taking false branch
203 q0 = e0-24*(jv+1);
204
205 /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
206 j = jv-jx;
207 m = jx+jk;
208 for(i=0; i<=m; i++,j++) f[i] = (j<0)? zero : (double) ipio2[j];
3
Assuming 'i' is > 'm'
4
Loop condition is false. Execution continues on line 211
209
210 /* compute q[0],q[1],...q[jk] */
211 for (i=0; i<=jk; i++) {
5
Assuming 'i' is > 'jk'
6
Loop condition is false. Execution continues on line 216
212 for(j=0,fw=0.0; j<=jx; j++) fw += x[j]*f[jx+i-j];
213 q[i] = fw;
214 }
215
216 jz = jk;
217recompute:
218 /* distill q[] into iq[] reversingly */
219 for(i=0,j=jz,z=q[jz]; j>0; i++,j--) {
7
Loop condition is false. Execution continues on line 226
22
Assuming 'j' is > 0
23
Loop condition is true. Entering loop body
24
Assuming 'j' is <= 0
25
Loop condition is false. Execution continues on line 226
220 fw = (double)((int)(twon24* z));
221 iq[i] = (int)(z-two24*fw);
222 z = q[j-1]+fw;
223 }
224
225 /* compute n */
226 z = scalbn(z,q0); /* actual value of z */
227 z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */
228 n = (int) z;
229 z -= (double)n;
230 ih = 0;
231 if(q0>0) { /* need iq[jz-1] to determine n */
8
Assuming 'q0' is <= 0
9
Taking false branch
26
Taking false branch
232 i = (iq[jz-1]>>(24-q0));
233 n += i;
234 iq[jz-1] -= i<<(24-q0);
235 ih = iq[jz-1]>>(23-q0);
236 }
237 else if(q0==0) ih = iq[jz-1]>>23;
10
Assuming 'q0' is not equal to 0
11
Taking false branch
27
Taking false branch
238 else if(z>=0.5) ih=2;
12
Taking false branch
28
Taking false branch
239
240 if(ih>0) { /* q > 0.5 */
13
Taking false branch
29
Taking false branch
241 n += 1;
242 carry = 0;
243 for(i=0; i<jz ; i++) { /* compute 1-q */
244 j = iq[i];
245 if(carry==0) {
246 if(j!=0) {
247 carry = 1;
248 iq[i] = 0x1000000- j;
249 }
250 } else iq[i] = 0xffffff - j;
251 }
252 if(q0>0) { /* rare case: chance is 1 in 12 */
253 switch(q0) {
254 case 1:
255 iq[jz-1] &= 0x7fffff;
256 break;
257 case 2:
258 iq[jz-1] &= 0x3fffff;
259 break;
260 }
261 }
262 if(ih==2) {
263 z = one - z;
264 if(carry!=0) z -= scalbn(one,q0);
265 }
266 }
267
268 /* check if recomputation is needed */
269 if(z==zero) {
14
Taking true branch
30
Taking false branch
270 j = 0;
271 for (i=jz-1; i>=jk; i--) j |= iq[i];
15
Loop condition is false. Execution continues on line 272
272 if(j==0) { /* need recomputation */
16
Taking true branch
273 for(k=1; iq[jk-k]==0; k++); /* k = no. of terms needed */
17
Loop condition is true. Entering loop body
18
Loop condition is true. Entering loop body
19
Loop condition is false. Execution continues on line 275
274
275 for(i=jz+1; i<=jz+k; i++) { /* add q[jz+1] to q[jz+k] */
20
Loop condition is false. Execution continues on line 280
276 f[jx+i] = (double) ipio2[jv+i];
277 for(j=0,fw=0.0; j<=jx; j++) fw += x[j]*f[jx+i-j];
278 q[i] = fw;
279 }
280 jz += k;
281 goto recompute;
21
Control jumps to line 219
282 }
283 }
284
285 /* chop off zero terms */
286 if(z==0.0) {
31
Taking true branch
287 jz -= 1;
288 q0 -= 24;
289 while(iq[jz]==0) {
32
Loop condition is true. Entering loop body
33
The left operand of '==' is a garbage value
290 jz--;
291 q0-=24;
292 }
293 } else { /* break z into 24-bit if necessary */
294 z = scalbn(z,-q0);
295 if(z>=two24) {
296 fw = (double)((int)(twon24*z));
297 iq[jz] = (int)(z-two24*fw);
298 jz += 1;
299 q0 += 24;
300 iq[jz] = (int) fw;
301 } else iq[jz] = (int) z ;
302 }
303
304 /* convert integer "bit" chunk to floating-point value */
305 fw = scalbn(one,q0);
306 for(i=jz; i>=0; i--) {
307 q[i] = fw*(double)iq[i];
308 fw*=twon24;
309 }
310
311 /* compute PIo2[0,...,jp]*q[jz,...,0] */
312 for(i=jz; i>=0; i--) {
313 for(fw=0.0,k=0; k<=jp&&k<=jz-i; k++) fw += PIo2[k]*q[i+k];
314 fq[jz-i] = fw;
315 }
316
317 /* compress fq[] into y[] */
318 switch(prec) {
319 case 0:
320 fw = 0.0;
321 for (i=jz; i>=0; i--) fw += fq[i];
322 y[0] = (ih==0)? fw: -fw;
323 break;
324 case 1:
325 case 2:
326 fw = 0.0;
327 for (i=jz; i>=0; i--) fw += fq[i];
328 y[0] = (ih==0)? fw: -fw;
329 fw = fq[0]-fw;
330 for (i=1; i<=jz; i++) fw += fq[i];
331 y[1] = (ih==0)? fw: -fw;
332 break;
333 case 3: /* painful */
334 for (i=jz; i>0; i--) {
335 fw = fq[i-1]+fq[i];
336 fq[i] += fq[i-1]-fw;
337 fq[i-1] = fw;
338 }
339 for (i=jz; i>1; i--) {
340 fw = fq[i-1]+fq[i];
341 fq[i] += fq[i-1]-fw;
342 fq[i-1] = fw;
343 }
344 for (fw=0.0,i=jz; i>=2; i--) fw += fq[i];
345 if(ih==0) {
346 y[0] = fq[0];
347 y[1] = fq[1];
348 y[2] = fw;
349 } else {
350 y[0] = -fq[0];
351 y[1] = -fq[1];
352 y[2] = -fw;
353 }
354 }
355 return n&7;
356}
diff --git a/scan-build/report-262893.html b/scan-build/report-262893.html deleted file mode 100644 index ab0222f8..00000000 --- a/scan-build/report-262893.html +++ /dev/null @@ -1,1287 +0,0 @@ - - - -lib/dconv/dragon4.cpp - - - - - - - - - - - - - - - - - - - - - - - - - -

Bug Summary

- - - - -
File:dconv/dragon4.cpp
Location:line 631, column 51
Description:The left operand of '-' is a garbage value
- -

Annotated Source Code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/******************************************************************************
2 Copyright (c) 2014 Ryan Juckett
3 http://www.ryanjuckett.com/
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20
21 3. This notice may not be removed or altered from any source
22 distribution.
23*******************************************************************************
24 Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
25 All rights reserved.
26
27 Redistribution and use in source and binary forms, with or without
28 modification, are permitted provided that the following conditions
29 are met:
30 1. Redistributions of source code must retain the above copyright
31 notice, this list of conditions and the following disclaimer.
32
33 2. Redistributions in binary form must reproduce the above copyright
34 notice, this list of conditions and the following disclaimer in the
35 documentation and/or other materials provided with the distribution.
36
37 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
38 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
40 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
41 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
46 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47
48 The origin source code can be obtained from:
49 http://www.ryanjuckett.com/
50
51******************************************************************************/
52
53#include "math.h"
54#include "dmath.h"
55#include "dragon4.h"
56
57//******************************************************************************
58// Maximum number of 32 bit blocks needed in high precision arithmetic
59// to print out 64 bit IEEE floating point values.
60//******************************************************************************
61const tU32 c_BigInt_MaxBlocks = 35;
62
63//******************************************************************************
64// This structure stores a high precision unsigned integer. It uses a buffer
65// of 32 bit integer blocks along with a length. The lowest bits of the integer
66// are stored at the start of the buffer and the length is set to the minimum
67// value that contains the integer. Thus, there are never any zero blocks at the
68// end of the buffer.
69//******************************************************************************
70struct tBigInt
71{
72 // Copy integer
73 tBigInt & operator=(const tBigInt &rhs)
74 {
75 tU32 length = rhs.m_length;
76 tU32 * pLhsCur = m_blocks;
77 for (const tU32 *pRhsCur = rhs.m_blocks, *pRhsEnd = pRhsCur + length;
78 pRhsCur != pRhsEnd;
79 ++pLhsCur, ++pRhsCur)
80 {
81 *pLhsCur = *pRhsCur;
82 }
83 m_length = length;
84 return *this;
85 }
86
87 // Data accessors
88 tU32 GetLength() const {
89 return m_length;
90 }
91 tU32 GetBlock(tU32 idx) const {
92 return m_blocks[idx];
93 }
94
95 // Zero helper functions
96 void SetZero() {
97 m_length = 0;
98 }
99 tB IsZero() const {
100 return m_length == 0;
101 }
102
103 // Basic type accessors
104 void SetU64(tU64 val)
105 {
106 if (val > 0xFFFFFFFF)
107 {
108 m_blocks[0] = val & 0xFFFFFFFF;
109 m_blocks[1] = (val >> 32) & 0xFFFFFFFF;
110 m_length = 2;
111 }
112 else if (val != 0)
113 {
114 m_blocks[0] = val & 0xFFFFFFFF;
115 m_length = 1;
116 }
117 else
118 {
119 m_length = 0;
120 }
121 }
122
123 void SetU32(tU32 val)
124 {
125 if (val != 0)
126 {
127 m_blocks[0] = val;
128 m_length = (val != 0);
129 }
130 else
131 {
132 m_length = 0;
133 }
134 }
135
136 tU32 GetU32() const {
137 return (m_length == 0) ? 0 : m_blocks[0];
138 }
139
140 // Member data
141 tU32 m_length;
142 tU32 m_blocks[c_BigInt_MaxBlocks];
143};
144
145//******************************************************************************
146// Returns 0 if (lhs = rhs), negative if (lhs < rhs), positive if (lhs > rhs)
147//******************************************************************************
148static tS32 BigInt_Compare(const tBigInt & lhs, const tBigInt & rhs)
149{
150 // A bigger length implies a bigger number.
151 tS32 lengthDiff = lhs.m_length - rhs.m_length;
152 if (lengthDiff != 0)
153 return lengthDiff;
154
155 // Compare blocks one by one from high to low.
156 for (tS32 i = lhs.m_length - 1; i >= 0; --i)
157 {
158 if (lhs.m_blocks[i] == rhs.m_blocks[i])
159 continue;
160 else if (lhs.m_blocks[i] > rhs.m_blocks[i])
161 return 1;
162 else
163 return -1;
164 }
165
166 // no blocks differed
167 return 0;
168}
169
170//******************************************************************************
171// result = lhs + rhs
172//******************************************************************************
173static void BigInt_Add(tBigInt * pResult, const tBigInt & lhs, const tBigInt & rhs)
174{
175 // determine which operand has the smaller length
176 const tBigInt * pLarge;
177 const tBigInt * pSmall;
178 if (lhs.m_length < rhs.m_length)
179 {
180 pSmall = &lhs;
181 pLarge = &rhs;
182 }
183 else
184 {
185 pSmall = &rhs;
186 pLarge = &lhs;
187 }
188
189 const tU32 largeLen = pLarge->m_length;
190 const tU32 smallLen = pSmall->m_length;
191
192 // The output will be at least as long as the largest input
193 pResult->m_length = largeLen;
194
195 // Add each block and add carry the overflow to the next block
196 tU64 carry = 0;
197 const tU32 * pLargeCur = pLarge->m_blocks;
198 const tU32 * pLargeEnd = pLargeCur + largeLen;
199 const tU32 * pSmallCur = pSmall->m_blocks;
200 const tU32 * pSmallEnd = pSmallCur + smallLen;
201 tU32 * pResultCur = pResult->m_blocks;
202 while (pSmallCur != pSmallEnd)
203 {
204 tU64 sum = carry + (tU64)(*pLargeCur) + (tU64)(*pSmallCur);
205 carry = sum >> 32;
206 (*pResultCur) = sum & 0xFFFFFFFF;
207 ++pLargeCur;
208 ++pSmallCur;
209 ++pResultCur;
210 }
211
212 // Add the carry to any blocks that only exist in the large operand
213 while (pLargeCur != pLargeEnd)
214 {
215 tU64 sum = carry + (tU64)(*pLargeCur);
216 carry = sum >> 32;
217 (*pResultCur) = sum & 0xFFFFFFFF;
218 ++pLargeCur;
219 ++pResultCur;
220 }
221
222 // If there's still a carry, append a new block
223 if (carry != 0)
224 {
225 RJ_ASSERT(carry == 1);
226 RJ_ASSERT((tU32)(pResultCur - pResult->m_blocks) == largeLen && (largeLen < c_BigInt_MaxBlocks));
227 *pResultCur = 1;
228 pResult->m_length = largeLen + 1;
229 }
230 else
231 {
232 pResult->m_length = largeLen;
233 }
234}
235
236//******************************************************************************
237// result = lhs * rhs
238//******************************************************************************
239static void BigInt_Multiply(tBigInt * pResult, const tBigInt &lhs, const tBigInt &rhs)
240{
241 RJ_ASSERT( pResult != &lhs && pResult != &rhs );
242
243 // determine which operand has the smaller length
244 const tBigInt * pLarge;
245 const tBigInt * pSmall;
246 if (lhs.m_length < rhs.m_length)
247 {
248 pSmall = &lhs;
249 pLarge = &rhs;
250 }
251 else
252 {
253 pSmall = &rhs;
254 pLarge = &lhs;
255 }
256
257 // set the maximum possible result length
258 tU32 maxResultLen = pLarge->m_length + pSmall->m_length;
259 RJ_ASSERT( maxResultLen <= c_BigInt_MaxBlocks );
260
261 // clear the result data
262 for(tU32 * pCur = pResult->m_blocks, *pEnd = pCur + maxResultLen; pCur != pEnd; ++pCur)
263 *pCur = 0;
264
265 // perform standard long multiplication
266 const tU32 *pLargeBeg = pLarge->m_blocks;
267 const tU32 *pLargeEnd = pLargeBeg + pLarge->m_length;
268
269 // for each small block
270 tU32 *pResultStart = pResult->m_blocks;
271 for(const tU32 *pSmallCur = pSmall->m_blocks, *pSmallEnd = pSmallCur + pSmall->m_length;
272 pSmallCur != pSmallEnd;
273 ++pSmallCur, ++pResultStart)
274 {
275 // if non-zero, multiply against all the large blocks and add into the result
276 const tU32 multiplier = *pSmallCur;
277 if (multiplier != 0)
278 {
279 const tU32 *pLargeCur = pLargeBeg;
280 tU32 *pResultCur = pResultStart;
281 tU64 carry = 0;
282 do
283 {
284 tU64 product = (*pResultCur) + (*pLargeCur)*(tU64)multiplier + carry;
285 carry = product >> 32;
286 *pResultCur = product & 0xFFFFFFFF;
287 ++pLargeCur;
288 ++pResultCur;
289 } while(pLargeCur != pLargeEnd);
290
291 RJ_ASSERT(pResultCur < pResult->m_blocks + maxResultLen);
292 *pResultCur = (tU32)(carry & 0xFFFFFFFF);
293 }
294 }
295
296 // check if the terminating block has no set bits
297 if (maxResultLen > 0 && pResult->m_blocks[maxResultLen - 1] == 0)
298 pResult->m_length = maxResultLen-1;
299 else
300 pResult->m_length = maxResultLen;
301}
302
303//******************************************************************************
304// result = lhs * rhs
305//******************************************************************************
306static void BigInt_Multiply(tBigInt * pResult, const tBigInt & lhs, tU32 rhs)
307{
308 // perform long multiplication
309 tU32 carry = 0;
310 tU32 *pResultCur = pResult->m_blocks;
311 const tU32 *pLhsCur = lhs.m_blocks;
312 const tU32 *pLhsEnd = lhs.m_blocks + lhs.m_length;
313 for ( ; pLhsCur != pLhsEnd; ++pLhsCur, ++pResultCur )
314 {
315 tU64 product = (tU64)(*pLhsCur) * rhs + carry;
316 *pResultCur = (tU32)(product & 0xFFFFFFFF);
317 carry = product >> 32;
318 }
319
320 // if there is a remaining carry, grow the array
321 if (carry != 0)
322 {
323 // grow the array
324 RJ_ASSERT(lhs.m_length + 1 <= c_BigInt_MaxBlocks);
325 *pResultCur = (tU32)carry;
326 pResult->m_length = lhs.m_length + 1;
327 }
328 else
329 {
330 pResult->m_length = lhs.m_length;
331 }
332}
333
334//******************************************************************************
335// result = in * 2
336//******************************************************************************
337static void BigInt_Multiply2(tBigInt * pResult, const tBigInt &in)
338{
339 // shift all the blocks by one
340 tU32 carry = 0;
341
342 tU32 *pResultCur = pResult->m_blocks;
343 const tU32 *pLhsCur = in.m_blocks;
344 const tU32 *pLhsEnd = in.m_blocks + in.m_length;
345 for ( ; pLhsCur != pLhsEnd; ++pLhsCur, ++pResultCur )
346 {
347 tU32 cur = *pLhsCur;
348 *pResultCur = (cur << 1) | carry;
349 carry = cur >> 31;
350 }
351
352 if (carry != 0)
353 {
354 // grow the array
355 RJ_ASSERT(in.m_length + 1 <= c_BigInt_MaxBlocks);
356 *pResultCur = carry;
357 pResult->m_length = in.m_length + 1;
358 }
359 else
360 {
361 pResult->m_length = in.m_length;
362 }
363}
364
365//******************************************************************************
366// result = result * 2
367//******************************************************************************
368static void BigInt_Multiply2(tBigInt * pResult)
369{
370 // shift all the blocks by one
371 tU32 carry = 0;
372
373 tU32 *pCur = pResult->m_blocks;
374 tU32 *pEnd = pResult->m_blocks + pResult->m_length;
375 for ( ; pCur != pEnd; ++pCur )
376 {
377 tU32 cur = *pCur;
378 *pCur = (cur << 1) | carry;
379 carry = cur >> 31;
380 }
381
382 if (carry != 0)
383 {
384 // grow the array
385 RJ_ASSERT(pResult->m_length + 1 <= c_BigInt_MaxBlocks);
386 *pCur = carry;
387 ++pResult->m_length;
388 }
389}
390
391//******************************************************************************
392// result = result * 10
393//******************************************************************************
394static void BigInt_Multiply10(tBigInt * pResult)
395{
396 // multiply all the blocks
397 tU64 carry = 0;
398
399 tU32 *pCur = pResult->m_blocks;
400 tU32 *pEnd = pResult->m_blocks + pResult->m_length;
401 for ( ; pCur != pEnd; ++pCur )
14
Loop condition is false. Execution continues on line 408
402 {
403 tU64 product = (tU64)(*pCur) * 10ull + carry;
404 (*pCur) = (tU32)(product & 0xFFFFFFFF);
405 carry = product >> 32;
406 }
407
408 if (carry != 0)
15
Taking false branch
409 {
410 // grow the array
411 RJ_ASSERT(pResult->m_length + 1 <= c_BigInt_MaxBlocks);
412 *pCur = (tU32)carry;
413 ++pResult->m_length;
414 }
415}
416
417//******************************************************************************
418//******************************************************************************
419static tU32 g_PowerOf10_U32[] =
420{
421 1, // 10 ^ 0
422 10, // 10 ^ 1
423 100, // 10 ^ 2
424 1000, // 10 ^ 3
425 10000, // 10 ^ 4
426 100000, // 10 ^ 5
427 1000000, // 10 ^ 6
428 10000000, // 10 ^ 7
429};
430
431//******************************************************************************
432// Note: This has a lot of wasted space in the big integer structures of the
433// early table entries. It wouldn't be terribly hard to make the multiply
434// function work on integer pointers with an array length instead of
435// the tBigInt struct which would allow us to store a minimal amount of
436// data here.
437//******************************************************************************
438static tBigInt g_PowerOf10_Big[] =
439{
440 // 10 ^ 8
441 { 1, { 100000000 } },
442 // 10 ^ 16
443 { 2, { 0x6fc10000, 0x002386f2 } },
444 // 10 ^ 32
445 { 4, { 0x00000000, 0x85acef81, 0x2d6d415b, 0x000004ee, } },
446 // 10 ^ 64
447 { 7, { 0x00000000, 0x00000000, 0xbf6a1f01, 0x6e38ed64, 0xdaa797ed, 0xe93ff9f4, 0x00184f03, } },
448 // 10 ^ 128
449 { 14, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x2e953e01, 0x03df9909, 0x0f1538fd,
450 0x2374e42f, 0xd3cff5ec, 0xc404dc08, 0xbccdb0da, 0xa6337f19, 0xe91f2603, 0x0000024e,
451 }
452 },
453 // 10 ^ 256
454 { 27, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
455 0x00000000, 0x982e7c01, 0xbed3875b, 0xd8d99f72, 0x12152f87, 0x6bde50c6, 0xcf4a6e70,
456 0xd595d80f, 0x26b2716e, 0xadc666b0, 0x1d153624, 0x3c42d35a, 0x63ff540e, 0xcc5573c0,
457 0x65f9ef17, 0x55bc28f2, 0x80dcc7f7, 0xf46eeddc, 0x5fdcefce, 0x000553f7,
458 }
459 }
460};
461
462//******************************************************************************
463// result = 10^exponent
464//******************************************************************************
465static void BigInt_Pow10(tBigInt * pResult, tU32 exponent)
466{
467 // make sure the exponent is within the bounds of the lookup table data
468 RJ_ASSERT(exponent < 512);
469
470 // create two temporary values to reduce large integer copy operations
471 tBigInt temp1;
472 tBigInt temp2;
473 tBigInt *pCurTemp = &temp1;
474 tBigInt *pNextTemp = &temp2;
475
476 // initialize the result by looking up a 32-bit power of 10 corresponding to the first 3 bits
477 tU32 smallExponent = exponent & 0x7;
478 pCurTemp->SetU32(g_PowerOf10_U32[smallExponent]);
479
480 // remove the low bits that we used for the 32-bit lookup table
481 exponent >>= 3;
482 tU32 tableIdx = 0;
483
484 // while there are remaining bits in the exponent to be processed
485 while (exponent != 0)
486 {
487 // if the current bit is set, multiply it with the corresponding power of 10
488 if(exponent & 1)
489 {
490 // multiply into the next temporary
491 BigInt_Multiply( pNextTemp, *pCurTemp, g_PowerOf10_Big[tableIdx] );
492
493 // swap to the next temporary
494 tBigInt * pSwap = pCurTemp;
495 pCurTemp = pNextTemp;
496 pNextTemp = pSwap;
497 }
498
499 // advance to the next bit
500 ++tableIdx;
501 exponent >>= 1;
502 }
503
504 // output the result
505 *pResult = *pCurTemp;
506}
507
508//******************************************************************************
509// result = in * 10^exponent
510//******************************************************************************
511static void BigInt_MultiplyPow10(tBigInt * pResult, const tBigInt & in, tU32 exponent)
512{
513 // make sure the exponent is within the bounds of the lookup table data
514 RJ_ASSERT(exponent < 512);
515
516 // create two temporary values to reduce large integer copy operations
517 tBigInt temp1;
518 tBigInt temp2;
519 tBigInt *pCurTemp = &temp1;
520 tBigInt *pNextTemp = &temp2;
521
522 // initialize the result by looking up a 32-bit power of 10 corresponding to the first 3 bits
523 tU32 smallExponent = exponent & 0x7;
524 if (smallExponent != 0)
525 {
526 BigInt_Multiply( pCurTemp, in, g_PowerOf10_U32[smallExponent] );
527 }
528 else
529 {
530 *pCurTemp = in;
531 }
532
533 // remove the low bits that we used for the 32-bit lookup table
534 exponent >>= 3;
535 tU32 tableIdx = 0;
536
537 // while there are remaining bits in the exponent to be processed
538 while (exponent != 0)
539 {
540 // if the current bit is set, multiply it with the corresponding power of 10
541 if(exponent & 1)
542 {
543 // multiply into the next temporary
544 BigInt_Multiply( pNextTemp, *pCurTemp, g_PowerOf10_Big[tableIdx] );
545
546 // swap to the next temporary
547 tBigInt * pSwap = pCurTemp;
548 pCurTemp = pNextTemp;
549 pNextTemp = pSwap;
550 }
551
552 // advance to the next bit
553 ++tableIdx;
554 exponent >>= 1;
555 }
556
557 // output the result
558 *pResult = *pCurTemp;
559}
560
561//******************************************************************************
562// result = 2^exponent
563//******************************************************************************
564static inline void BigInt_Pow2(tBigInt * pResult, tU32 exponent)
565{
566 tU32 blockIdx = exponent / 32;
567 RJ_ASSERT( blockIdx < c_BigInt_MaxBlocks );
568
569 for ( tU32 i = 0; i <= blockIdx; ++i)
570 pResult->m_blocks[i] = 0;
571
572 pResult->m_length = blockIdx + 1;
573
574 tU32 bitIdx = (exponent % 32);
575 pResult->m_blocks[blockIdx] |= (1 << bitIdx);
576}
577
578//******************************************************************************
579// This function will divide two large numbers under the assumption that the
580// result is within the range [0,10) and the input numbers have been shifted
581// to satisfy:
582// - The highest block of the divisor is greater than or equal to 8 such that
583// there is enough precision to make an accurate first guess at the quotient.
584// - The highest block of the divisor is less than the maximum value on an
585// unsigned 32-bit integer such that we can safely increment without overflow.
586// - The dividend does not contain more blocks than the divisor such that we
587// can estimate the quotient by dividing the equivalently placed high blocks.
588//
589// quotient = floor(dividend / divisor)
590// remainder = dividend - quotient*divisor
591//
592// pDividend is updated to be the remainder and the quotient is returned.
593//******************************************************************************
594static tU32 BigInt_DivideWithRemainder_MaxQuotient9(tBigInt * pDividend, const tBigInt & divisor)
595{
596 // Check that the divisor has been correctly shifted into range and that it is not
597 // smaller than the dividend in length.
598 RJ_ASSERT( !divisor.IsZero() &&
599 divisor.m_blocks[divisor.m_length-1] >= 8 &&
600 divisor.m_blocks[divisor.m_length-1] < 0xFFFFFFFF &&
601 pDividend->m_length <= divisor.m_length );
602
603 // If the dividend is smaller than the divisor, the quotient is zero and the divisor is already
604 // the remainder.
605 tU32 length = divisor.m_length;
606 if (pDividend->m_length < divisor.m_length)
34
Taking false branch
607 return 0;
608
609 const tU32 * pFinalDivisorBlock = divisor.m_blocks + length - 1;
610 tU32 * pFinalDividendBlock = pDividend->m_blocks + length - 1;
611
612 // Compute an estimated quotient based on the high block value. This will either match the actual quotient or
613 // undershoot by one.
614 tU32 quotient = *pFinalDividendBlock / (*pFinalDivisorBlock + 1);
615 RJ_ASSERT(quotient <= 9);
616
617 // Divide out the estimated quotient
618 if (quotient != 0)
35
Assuming 'quotient' is not equal to 0
36
Taking true branch
619 {
620 // dividend = dividend - divisor*quotient
621 const tU32 *pDivisorCur = divisor.m_blocks;
622 tU32 *pDividendCur = pDividend->m_blocks;
623
624 tU64 borrow = 0;
625 tU64 carry = 0;
626 do
37
Loop condition is true. Execution continues on line 628
627 {
628 tU64 product = (tU64)*pDivisorCur * (tU64)quotient + carry;
629 carry = product >> 32;
630
631 tU64 difference = (tU64)*pDividendCur - (product & 0xFFFFFFFF) - borrow;
38
The left operand of '-' is a garbage value
632 borrow = (difference >> 32) & 1;
633
634 *pDividendCur = difference & 0xFFFFFFFF;
635
636 ++pDivisorCur;
637 ++pDividendCur;
638 } while(pDivisorCur <= pFinalDivisorBlock);
639
640 // remove all leading zero blocks from dividend
641 while (length > 0 && pDividend->m_blocks[length - 1] == 0)
642 --length;
643
644 pDividend->m_length = length;
645 }
646
647 // If the dividend is still larger than the divisor, we overshot our estimate quotient. To correct,
648 // we increment the quotient and subtract one more divisor from the dividend.
649 if ( BigInt_Compare(*pDividend, divisor) >= 0 )
650 {
651 ++quotient;
652
653 // dividend = dividend - divisor
654 const tU32 *pDivisorCur = divisor.m_blocks;
655 tU32 *pDividendCur = pDividend->m_blocks;
656
657 tU64 borrow = 0;
658 do
659 {
660 tU64 difference = (tU64)*pDividendCur - (tU64)*pDivisorCur - borrow;
661 borrow = (difference >> 32) & 1;
662
663 *pDividendCur = difference & 0xFFFFFFFF;
664
665 ++pDivisorCur;
666 ++pDividendCur;
667 } while(pDivisorCur <= pFinalDivisorBlock);
668
669 // remove all leading zero blocks from dividend
670 while (length > 0 && pDividend->m_blocks[length - 1] == 0)
671 --length;
672
673 pDividend->m_length = length;
674 }
675
676 return quotient;
677}
678
679//******************************************************************************
680// result = result << shift
681//******************************************************************************
682static void BigInt_ShiftLeft(tBigInt * pResult, tU32 shift)
683{
684 RJ_ASSERT( shift != 0 );
685
686 tU32 shiftBlocks = shift / 32;
687 tU32 shiftBits = shift % 32;
688
689 // process blocks high to low so that we can safely process in place
690 const tU32 * pInBlocks = pResult->m_blocks;
691 tS32 inLength = pResult->m_length;
692 RJ_ASSERT( inLength + shiftBlocks < c_BigInt_MaxBlocks );
693
694 // check if the shift is block aligned
695 if (shiftBits == 0)
25
Taking false branch
696 {
697 // copy blcoks from high to low
698 for (tU32 * pInCur = pResult->m_blocks + inLength, *pOutCur = pInCur + shiftBlocks;
699 pInCur >= pInBlocks;
700 --pInCur, --pOutCur)
701 {
702 *pOutCur = *pInCur;
703 }
704
705 // zero the remaining low blocks
706 for ( tU32 i = 0; i < shiftBlocks; ++i)
707 pResult->m_blocks[i] = 0;
708
709 pResult->m_length += shiftBlocks;
710 }
711 // else we need to shift partial blocks
712 else
713 {
714 tS32 inBlockIdx = inLength - 1;
715 tU32 outBlockIdx = inLength + shiftBlocks;
716
717 // set the length to hold the shifted blocks
718 RJ_ASSERT( outBlockIdx < c_BigInt_MaxBlocks );
719 pResult->m_length = outBlockIdx + 1;
720
721 // output the initial blocks
722 const tU32 lowBitsShift = (32 - shiftBits);
723 tU32 highBits = 0;
724 tU32 block = pResult->m_blocks[inBlockIdx];
725 tU32 lowBits = block >> lowBitsShift;
726 while ( inBlockIdx > 0 )
26
Loop condition is false. Execution continues on line 740
727 {
728 pResult->m_blocks[outBlockIdx] = highBits | lowBits;
729 highBits = block << shiftBits;
730
731 --inBlockIdx;
732 --outBlockIdx;
733
734 block = pResult->m_blocks[inBlockIdx];
735 lowBits = block >> lowBitsShift;
736 }
737
738 // output the final blocks
739 RJ_ASSERT( outBlockIdx == shiftBlocks + 1 );
740 pResult->m_blocks[outBlockIdx] = highBits | lowBits;
741 pResult->m_blocks[outBlockIdx-1] = block << shiftBits;
742
743 // zero the remaining low blocks
744 for ( tU32 i = 0; i < shiftBlocks; ++i)
27
Loop condition is false. Execution continues on line 748
745 pResult->m_blocks[i] = 0;
746
747 // check if the terminating block has no set bits
748 if (pResult->m_blocks[pResult->m_length - 1] == 0)
28
Taking false branch
749 --pResult->m_length;
750 }
751}
752
753//******************************************************************************
754// This is an implementation the Dragon4 algorithm to convert a binary number
755// in floating point format to a decimal number in string format. The function
756// returns the number of digits written to the output buffer and the output is
757// not NUL terminated.
758//
759// The floating point input value is (mantissa * 2^exponent).
760//
761// See the following papers for more information on the algorithm:
762// "How to Print Floating-Point Numbers Accurately"
763// Steele and White
764// http://kurtstephens.com/files/p372-steele.pdf
765// "Printing Floating-Point Numbers Quickly and Accurately"
766// Burger and Dybvig
767// http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.4656&rep=rep1&type=pdf
768//******************************************************************************
769tU32 Dragon4
770(
771 const tU64 mantissa, // value significand
772 const tS32 exponent, // value exponent in base 2
773 const tU32 mantissaHighBitIdx, // index of the highest set mantissa bit
774 const tB hasUnequalMargins, // is the high margin twice as large as the low margin
775 const tCutoffMode cutoffMode, // how to determine output length
776 tU32 cutoffNumber, // parameter to the selected cutoffMode
777 tC8 * pOutBuffer, // buffer to output into
778 tU32 bufferSize, // maximum characters that can be printed to pOutBuffer
779 tS32 * pOutExponent // the base 10 exponent of the first digit
780)
781{
782 tC8 * pCurDigit = pOutBuffer;
783
784 RJ_ASSERT( bufferSize > 0 );
785
786 // if the mantissa is zero, the value is zero regardless of the exponent
787 if (mantissa == 0)
1
Assuming 'mantissa' is not equal to 0
2
Taking false branch
788 {
789 *pCurDigit = '0';
790 *pOutExponent = 0;
791 return 1;
792 }
793
794 // compute the initial state in integral form such that
795 // value = scaledValue / scale
796 // marginLow = scaledMarginLow / scale
797 tBigInt scale; // positive scale applied to value and margin such that they can be
798 // represented as whole numbers
799 tBigInt scaledValue; // scale * mantissa
800 tBigInt scaledMarginLow; // scale * 0.5 * (distance between this floating-point number and its
801 // immediate lower value)
802
803 // For normalized IEEE floating point values, each time the exponent is incremented the margin also
804 // doubles. That creates a subset of transition numbers where the high margin is twice the size of
805 // the low margin.
806 tBigInt * pScaledMarginHigh;
807 tBigInt optionalMarginHigh;
808
809 if ( hasUnequalMargins )
3
Assuming 'hasUnequalMargins' is 0
4
Taking false branch
810 {
811 // if we have no fractional component
812 if (exponent > 0)
813 {
814 // 1) Expand the input value by multiplying out the mantissa and exponent. This represents
815 // the input value in its whole number representation.
816 // 2) Apply an additional scale of 2 such that later comparisons against the margin values
817 // are simplified.
818 // 3) Set the margin value to the lowest mantissa bit's scale.
819
820 // scaledValue = 2 * 2 * mantissa*2^exponent
821 scaledValue.SetU64( 4 * mantissa );
822 BigInt_ShiftLeft( &scaledValue, exponent );
823
824 // scale = 2 * 2 * 1
825 scale.SetU32( 4 );
826
827 // scaledMarginLow = 2 * 2^(exponent-1)
828 BigInt_Pow2( &scaledMarginLow, exponent );
829
830 // scaledMarginHigh = 2 * 2 * 2^(exponent-1)
831 BigInt_Pow2( &optionalMarginHigh, exponent + 1 );
832 }
833 // else we have a fractional exponent
834 else
835 {
836 // In order to track the mantissa data as an integer, we store it as is with a large scale
837
838 // scaledValue = 2 * 2 * mantissa
839 scaledValue.SetU64( 4 * mantissa );
840
841 // scale = 2 * 2 * 2^(-exponent)
842 BigInt_Pow2(&scale, -exponent + 2 );
843
844 // scaledMarginLow = 2 * 2^(-1)
845 scaledMarginLow.SetU32( 1 );
846
847 // scaledMarginHigh = 2 * 2 * 2^(-1)
848 optionalMarginHigh.SetU32( 2 );
849 }
850
851 // the high and low margins are different
852 pScaledMarginHigh = &optionalMarginHigh;
853 }
854 else
855 {
856 // if we have no fractional component
857 if (exponent > 0)
5
Assuming 'exponent' is <= 0
6
Taking false branch
858 {
859 // 1) Expand the input value by multiplying out the mantissa and exponent. This represents
860 // the input value in its whole number representation.
861 // 2) Apply an additional scale of 2 such that later comparisons against the margin values
862 // are simplified.
863 // 3) Set the margin value to the lowest mantissa bit's scale.
864
865 // scaledValue = 2 * mantissa*2^exponent
866 scaledValue.SetU64( 2 * mantissa );
867 BigInt_ShiftLeft( &scaledValue, exponent );
868
869 // scale = 2 * 1
870 scale.SetU32( 2 );
871
872 // scaledMarginLow = 2 * 2^(exponent-1)
873 BigInt_Pow2( &scaledMarginLow, exponent );
874 }
875 // else we have a fractional exponent
876 else
877 {
878 // In order to track the mantissa data as an integer, we store it as is with a large scale
879
880 // scaledValue = 2 * mantissa
881 scaledValue.SetU64( 2 * mantissa );
882
883 // scale = 2 * 2^(-exponent)
884 BigInt_Pow2(&scale, -exponent + 1 );
885
886 // scaledMarginLow = 2 * 2^(-1)
887 scaledMarginLow.SetU32( 1 );
888 }
889
890 // the high and low margins are equal
891 pScaledMarginHigh = &scaledMarginLow;
892 }
893
894 // Compute an estimate for digitExponent that will be correct or undershoot by one.
895 // This optimization is based on the paper "Printing Floating-Point Numbers Quickly and Accurately"
896 // by Burger and Dybvig http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.4656&rep=rep1&type=pdf
897 // We perform an additional subtraction of 0.69 to increase the frequency of a failed estimate
898 // because that lets us take a faster branch in the code. 0.69 is chosen because 0.69 + log10(2) is
899 // less than one by a reasonable epsilon that will account for any floating point error.
900 //
901 // We want to set digitExponent to floor(log10(v)) + 1
902 // v = mantissa*2^exponent
903 // log2(v) = log2(mantissa) + exponent;
904 // log10(v) = log2(v) * log10(2)
905 // floor(log2(v)) = mantissaHighBitIdx + exponent;
906 // log10(v) - log10(2) < (mantissaHighBitIdx + exponent) * log10(2) <= log10(v)
907 // log10(v) < (mantissaHighBitIdx + exponent) * log10(2) + log10(2) <= log10(v) + log10(2)
908 // floor( log10(v) ) < ceil( (mantissaHighBitIdx + exponent) * log10(2) ) <= floor( log10(v) ) + 1
909 const tF64 log10_2 = 0.30102999566398119521373889472449;
910 tS32 digitExponent = (tS32)(ceil(tF64((tS32)mantissaHighBitIdx + exponent) * log10_2 - 0.69));
911
912 // if the digit exponent is smaller than the smallest desired digit for fractional cutoff,
913 // pull the digit back into legal range at which point we will round to the appropriate value.
914 // Note that while our value for digitExponent is still an estimate, this is safe because it
915 // only increases the number. This will either correct digitExponent to an accurate value or it
916 // will clamp it above the accurate value.
917 if (cutoffMode == CutoffMode_FractionLength && digitExponent <= -(tS32)cutoffNumber)
7
Assuming 'cutoffMode' is not equal to CutoffMode_FractionLength
918 {
919 digitExponent = -(tS32)cutoffNumber + 1;
920 }
921
922 // Divide value by 10^digitExponent.
923 if (digitExponent > 0)
8
Assuming 'digitExponent' is <= 0
9
Taking false branch
924 {
925 // The exponent is positive creating a division so we multiply up the scale.
926 tBigInt temp;
927 BigInt_MultiplyPow10( &temp, scale, digitExponent );
928 scale = temp;
929 }
930 else if (digitExponent < 0)
10
Assuming 'digitExponent' is >= 0
11
Taking false branch
931 {
932 // The exponent is negative creating a multiplication so we multiply up the scaledValue,
933 // scaledMarginLow and scaledMarginHigh.
934 tBigInt pow10;
935 BigInt_Pow10( &pow10, -digitExponent);
936
937 tBigInt temp;
938 BigInt_Multiply( &temp, scaledValue, pow10);
939 scaledValue = temp;
940
941 BigInt_Multiply( &temp, scaledMarginLow, pow10);
942 scaledMarginLow = temp;
943
944 if (pScaledMarginHigh != &scaledMarginLow)
945 BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow );
946 }
947
948 // If (value + marginHigh) >= 1, our estimate for digitExponent was too low
949 tBigInt scaledValueHigh;
950 BigInt_Add( &scaledValueHigh, scaledValue, *pScaledMarginHigh );
951 if( BigInt_Compare(scaledValueHigh,scale) >= 0 )
12
Taking false branch
952 {
953 // The exponent estimate was incorrect.
954 // Increment the exponent and don't perform the premultiply needed
955 // for the first loop iteration.
956 digitExponent = digitExponent + 1;
957 }
958 else
959 {
960 // The exponent estimate was correct.
961 // Multiply larger by the output base to prepare for the first loop iteration.
962 BigInt_Multiply10( &scaledValue );
13
Calling 'BigInt_Multiply10'
16
Returning from 'BigInt_Multiply10'
963 BigInt_Multiply10( &scaledMarginLow );
964 if (pScaledMarginHigh != &scaledMarginLow)
17
Taking false branch
965 BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow );
966 }
967
968 // Compute the cutoff exponent (the exponent of the final digit to print).
969 // Default to the maximum size of the output buffer.
970 tS32 cutoffExponent = digitExponent - bufferSize;
971 switch(cutoffMode)
18
Control jumps to 'case CutoffMode_TotalLength:' at line 978
972 {
973 // print digits until we pass the accuracy margin limits or buffer size
974 case CutoffMode_Unique:
975 break;
976
977 // print cutoffNumber of digits or until we reach the buffer size
978 case CutoffMode_TotalLength:
979 {
980 tS32 desiredCutoffExponent = digitExponent - (tS32)cutoffNumber;
981 if (desiredCutoffExponent > cutoffExponent)
19
Taking false branch
982 cutoffExponent = desiredCutoffExponent;
983 }
984 break;
20
Execution continues on line 997
985
986 // print cutoffNumber digits past the decimal point or until we reach the buffer size
987 case CutoffMode_FractionLength:
988 {
989 tS32 desiredCutoffExponent = -(tS32)cutoffNumber;
990 if (desiredCutoffExponent > cutoffExponent)
991 cutoffExponent = desiredCutoffExponent;
992 }
993 break;
994 }
995
996 // Output the exponent of the first digit we will print
997 *pOutExponent = digitExponent-1;
998
999 // In preparation for calling BigInt_DivideWithRemainder_MaxQuotient9(),
1000 // we need to scale up our values such that the highest block of the denominator
1001 // is greater than or equal to 8. We also need to guarantee that the numerator
1002 // can never have a length greater than the denominator after each loop iteration.
1003 // This requires the highest block of the denominator to be less than or equal to
1004 // 429496729 which is the highest number that can be multiplied by 10 without
1005 // overflowing to a new block.
1006 RJ_ASSERT( scale.GetLength() > 0 );
1007 tU32 hiBlock = scale.GetBlock( scale.GetLength() - 1 );
1008 if (hiBlock < 8 || hiBlock > 429496729)
21
Assuming 'hiBlock' is >= 8
22
Assuming 'hiBlock' is > 429496729
23
Taking true branch
1009 {
1010 // Perform a bit shift on all values to get the highest block of the denominator into
1011 // the range [8,429496729]. We are more likely to make accurate quotient estimations
1012 // in BigInt_DivideWithRemainder_MaxQuotient9() with higher denominator values so
1013 // we shift the denominator to place the highest bit at index 27 of the highest block.
1014 // This is safe because (2^28 - 1) = 268435455 which is less than 429496729. This means
1015 // that all values with a highest bit at index 27 are within range.
1016 tU32 hiBlockLog2 = LogBase2(hiBlock);
1017 RJ_ASSERT(hiBlockLog2 < 3 || hiBlockLog2 > 27);
1018 tU32 shift = (32 + 27 - hiBlockLog2) % 32;
1019
1020 BigInt_ShiftLeft( &scale, shift );
1021 BigInt_ShiftLeft( &scaledValue, shift);
24
Calling 'BigInt_ShiftLeft'
29
Returning from 'BigInt_ShiftLeft'
1022 BigInt_ShiftLeft( &scaledMarginLow, shift);
1023 if (pScaledMarginHigh != &scaledMarginLow)
30
Taking false branch
1024 BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow );
1025 }
1026
1027 // These values are used to inspect why the print loop terminated so we can properly
1028 // round the final digit.
1029 tB low; // did the value get within marginLow distance from zero
1030 tB high; // did the value get within marginHigh distance from one
1031 tU32 outputDigit; // current digit being output
1032
1033 if (cutoffMode == CutoffMode_Unique)
31
Taking false branch
1034 {
1035 // For the unique cutoff mode, we will try to print until we have reached a level of
1036 // precision that uniquely distinguishes this value from its neighbors. If we run
1037 // out of space in the output buffer, we terminate early.
1038 for (;;)
1039 {
1040 digitExponent = digitExponent-1;
1041
1042 // divide out the scale to extract the digit
1043 outputDigit = BigInt_DivideWithRemainder_MaxQuotient9(&scaledValue, scale);
1044 RJ_ASSERT( outputDigit < 10 );
1045
1046 // update the high end of the value
1047 BigInt_Add( &scaledValueHigh, scaledValue, *pScaledMarginHigh );
1048
1049 // stop looping if we are far enough away from our neighboring values
1050 // or if we have reached the cutoff digit
1051 low = BigInt_Compare(scaledValue, scaledMarginLow) < 0;
1052 high = BigInt_Compare(scaledValueHigh, scale) > 0;
1053 if (low | high | (digitExponent == cutoffExponent))
1054 break;
1055
1056 // store the output digit
1057 *pCurDigit = (tC8)('0' + outputDigit);
1058 ++pCurDigit;
1059
1060 // multiply larger by the output base
1061 BigInt_Multiply10( &scaledValue );
1062 BigInt_Multiply10( &scaledMarginLow );
1063 if (pScaledMarginHigh != &scaledMarginLow)
1064 BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow );
1065 }
1066 }
1067 else
1068 {
1069 // For length based cutoff modes, we will try to print until we
1070 // have exhausted all precision (i.e. all remaining digits are zeros) or
1071 // until we reach the desired cutoff digit.
1072 low = false;
1073 high = false;
1074
1075 for (;;)
32
Loop condition is true. Entering loop body
1076 {
1077 digitExponent = digitExponent-1;
1078
1079 // divide out the scale to extract the digit
1080 outputDigit = BigInt_DivideWithRemainder_MaxQuotient9(&scaledValue, scale);
33
Calling 'BigInt_DivideWithRemainder_MaxQuotient9'
1081 RJ_ASSERT( outputDigit < 10 );
1082
1083 if ( scaledValue.IsZero() | (digitExponent == cutoffExponent) )
1084 break;
1085
1086 // store the output digit
1087 *pCurDigit = (tC8)('0' + outputDigit);
1088 ++pCurDigit;
1089
1090 // multiply larger by the output base
1091 BigInt_Multiply10(&scaledValue);
1092 }
1093 }
1094
1095 // round off the final digit
1096 // default to rounding down if value got too close to 0
1097 tB roundDown = low;
1098
1099 // if it is legal to round up and down
1100 if (low == high)
1101 {
1102 // round to the closest digit by comparing value with 0.5. To do this we need to convert
1103 // the inequality to large integer values.
1104 // compare( value, 0.5 )
1105 // compare( scale * value, scale * 0.5 )
1106 // compare( 2 * scale * value, scale )
1107 BigInt_Multiply2(&scaledValue);
1108 tS32 compare = BigInt_Compare(scaledValue, scale);
1109 roundDown = compare < 0;
1110
1111 // if we are directly in the middle, round towards the even digit (i.e. IEEE rouding rules)
1112 if (compare == 0)
1113 roundDown = (outputDigit & 1) == 0;
1114 }
1115
1116 // print the rounded digit
1117 if (roundDown)
1118 {
1119 *pCurDigit = (tC8)('0' + outputDigit);
1120 ++pCurDigit;
1121 }
1122 else
1123 {
1124 // handle rounding up
1125 if (outputDigit == 9)
1126 {
1127 // find the first non-nine prior digit
1128 for (;;)
1129 {
1130 // if we are at the first digit
1131 if (pCurDigit == pOutBuffer)
1132 {
1133 // output 1 at the next highest exponent
1134 *pCurDigit = '1';
1135 ++pCurDigit;
1136 *pOutExponent += 1;
1137 break;
1138 }
1139
1140 --pCurDigit;
1141 if (*pCurDigit != '9')
1142 {
1143 // increment the digit
1144 *pCurDigit += 1;
1145 ++pCurDigit;
1146 break;
1147 }
1148 }
1149 }
1150 else
1151 {
1152 // values in the range [0,8] can perform a simple round up
1153 *pCurDigit = (tC8)('0' + outputDigit + 1);
1154 ++pCurDigit;
1155 }
1156 }
1157
1158 // return the number of digits output
1159 RJ_ASSERT(pCurDigit - pOutBuffer <= (tPtrDiff)bufferSize);
1160 return pCurDigit - pOutBuffer;
1161}
diff --git a/scan-build/report-273e84.html b/scan-build/report-273e84.html deleted file mode 100644 index 1bcb9eff..00000000 --- a/scan-build/report-273e84.html +++ /dev/null @@ -1,349 +0,0 @@ - - - -lib/real/expm1.c - - - - - - - - - - - - - - - - - - - - - - - - - -

Bug Summary

- - - - -
File:real/expm1.c
Location:line 167, column 10
Description:Value stored to 'y' is never read
- -

Annotated Source Code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/* @(#)s_expm1.c 1.5 04/04/22 */
2
3/*
4 * Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * The origin source code can be obtained from:
28 * http://www.netlib.org/fdlibm/s_expm1.c
29 *
30 */
31
32/*
33 * ====================================================
34 * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
35 *
36 * Permission to use, copy, modify, and distribute this
37 * software is freely granted, provided that this notice
38 * is preserved.
39 * ====================================================
40 *
41 */
42
43#include "prim.h"
44#include "math.h"
45
46/* expm1(x)
47 * Returns exp(x)-1, the exponential of x minus 1.
48 *
49 * Method
50 * 1. Argument reduction:
51 * Given x, find r and integer k such that
52 *
53 * x = k*ln2 + r, |r| <= 0.5*ln2 ~ 0.34658
54 *
55 * Here a correction term c will be computed to compensate
56 * the error in r when rounded to a floating-point number.
57 *
58 * 2. Approximating expm1(r) by a special rational function on
59 * the interval [0,0.34658]:
60 * Since
61 * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ...
62 * we define R1(r*r) by
63 * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r)
64 * That is,
65 * R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
66 * = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
67 * = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
68 * We use a special Remes algorithm on [0,0.347] to generate
69 * a polynomial of degree 5 in r*r to approximate R1. The
70 * maximum error of this polynomial approximation is bounded
71 * by 2**-61. In other words,
72 * R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5
73 * where Q1 = -1.6666666666666567384E-2,
74 * Q2 = 3.9682539681370365873E-4,
75 * Q3 = -9.9206344733435987357E-6,
76 * Q4 = 2.5051361420808517002E-7,
77 * Q5 = -6.2843505682382617102E-9;
78 * (where z=r*r, and the values of Q1 to Q5 are listed below)
79 * with error bounded by
80 * | 5 | -61
81 * | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2
82 * | |
83 *
84 * expm1(r) = exp(r)-1 is then computed by the following
85 * specific way which minimize the accumulation rounding error:
86 * 2 3
87 * r r [ 3 - (R1 + R1*r/2) ]
88 * expm1(r) = r + --- + --- * [--------------------]
89 * 2 2 [ 6 - r*(3 - R1*r/2) ]
90 *
91 * To compensate the error in the argument reduction, we use
92 * expm1(r+c) = expm1(r) + c + expm1(r)*c
93 * ~ expm1(r) + c + r*c
94 * Thus c+r*c will be added in as the correction terms for
95 * expm1(r+c). Now rearrange the term to avoid optimization
96 * screw up:
97 * ( 2 2 )
98 * ({ ( r [ R1 - (3 - R1*r/2) ] ) } r )
99 * expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- )
100 * ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 )
101 * ( )
102 *
103 * = r - E
104 * 3. Scale back to obtain expm1(x):
105 * From step 1, we have
106 * expm1(x) = either 2^k*[expm1(r)+1] - 1
107 * = or 2^k*[expm1(r) + (1-2^-k)]
108 * 4. Implementation notes:
109 * (A). To save one multiplication, we scale the coefficient Qi
110 * to Qi*2^i, and replace z by (x^2)/2.
111 * (B). To achieve maximum accuracy, we compute expm1(x) by
112 * (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf)
113 * (ii) if k=0, return r-E
114 * (iii) if k=-1, return 0.5*(r-E)-0.5
115 * (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E)
116 * else return 1.0+2.0*(r-E);
117 * (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1)
118 * (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else
119 * (vii) return 2^k(1-((E+2^-k)-r))
120 *
121 * Special cases:
122 * expm1(INF) is INF, expm1(NaN) is NaN;
123 * expm1(-INF) is -1, and
124 * for finite argument, only expm1(0)=0 is exact.
125 *
126 * Accuracy:
127 * according to an error analysis, the error is always less than
128 * 1 ulp (unit in the last place).
129 *
130 * Misc. info.
131 * For IEEE double
132 * if x > 7.09782712893383973096e+02 then expm1(x) overflow
133 *
134 * Constants:
135 * The hexadecimal values are the intended ones for the following
136 * constants. The decimal values may be used, provided that the
137 * compiler will convert from decimal to binary accurately enough
138 * to produce the hexadecimal values shown.
139 */
140
141static const double
142one = 1.0,
143huge = 1.0e+300,
144tiny = 1.0e-300,
145o_threshold = 7.09782712893383973096e+02,/* 0x40862E42, 0xFEFA39EF */
146ln2_hi = 6.93147180369123816490e-01,/* 0x3fe62e42, 0xfee00000 */
147ln2_lo = 1.90821492927058770002e-10,/* 0x3dea39ef, 0x35793c76 */
148invln2 = 1.44269504088896338700e+00,/* 0x3ff71547, 0x652b82fe */
149 /* scaled coefficients related to expm1 */
150Q1 = -3.33333333333331316428e-02, /* BFA11111 111110F4 */
151Q2 = 1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */
152Q3 = -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */
153Q4 = 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */
154Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */
155
156double expm1(double x)
157{
158 double y,hi,lo,c,t,e,hxs,hfx,r1;
159 sword k,xsb;
160 uword hx;
161
162 c = 0.0;
163
164 GET_HIGH_WORD(hx,x)do { ieee_double_shape_type gh_u; gh_u.value = (x); (hx) = gh_u
.parts.msw; } while (0)
; /* high word of x */
165 xsb = hx&0x80000000; /* sign bit of x */
166 if(xsb==0) y=x;
167 else y= -x; /* y = |x| */
Value stored to 'y' is never read
168 hx &= 0x7fffffff; /* high word of |x| */
169
170 /* filter out huge and non-finite argument */
171 if(hx >= 0x4043687A) { /* if |x|>=56*ln2 */
172 if(hx >= 0x40862E42) { /* if |x|>=709.78... */
173 if(hx>=0x7ff00000) {
174 uword low;
175 GET_LOW_WORD(low,x)do { ieee_double_shape_type gl_u; gl_u.value = (x); (low) = gl_u
.parts.lsw; } while (0)
;
176 if(((hx&0xfffff)|low)!=0)
177 return x+x; /* NaN */
178 else return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */
179 }
180 if(x > o_threshold) return huge*huge; /* overflow */
181 }
182 if(xsb!=0) { /* x < -56*ln2, return -1.0 with inexact */
183 if(x+tiny<0.0) /* raise inexact */
184 return tiny-one; /* return -1 */
185 }
186 }
187
188 /* argument reduction */
189 if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
190 if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
191 if(xsb==0)
192 {
193 hi = x - ln2_hi;
194 lo = ln2_lo;
195 k = 1;
196 }
197 else
198 {
199 hi = x + ln2_hi;
200 lo = -ln2_lo;
201 k = -1;
202 }
203 } else {
204 k = (sword)(invln2*x+((xsb==0)?0.5:-0.5));
205 t = k;
206 hi = x - t*ln2_hi; /* t*ln2_hi is exact here */
207 lo = t*ln2_lo;
208 }
209 x = hi - lo;
210 c = (hi-x)-lo;
211 }
212 else if(hx < 0x3c900000) { /* when |x|<2**-54, return x */
213 t = huge+x; /* return x with inexact flags when x!=0 */
214 return x - (t-(huge+x));
215 }
216 else k = 0;
217
218 /* x is now in primary range */
219 hfx = 0.5*x;
220 hxs = x*hfx;
221 r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))));
222 t = 3.0-r1*hfx;
223 e = hxs*((r1-t)/(6.0 - x*t));
224 if(k==0) return x - (x*e-hxs); /* c is 0 */
225 else {
226 e = (x*(e-c)-c);
227 e -= hxs;
228 if(k== -1) return 0.5*(x-e)-0.5;
229 if(k==1) {
230 if(x < -0.25) return -2.0*(e-(x+0.5));
231 else return one+2.0*(x-e);
232 }
233 if (k <= -2 || k>56) { /* suffice to return exp(x)-1 */
234 uword hy;
235
236 y = one-(e-x);
237 GET_HIGH_WORD(hy,y)do { ieee_double_shape_type gh_u; gh_u.value = (y); (hy) = gh_u
.parts.msw; } while (0)
;
238 SET_HIGH_WORD(y, hy + (k<<20))do { ieee_double_shape_type sh_u; sh_u.value = (y); sh_u.parts
.msw = (hy + (k<<20)); (y) = sh_u.value; } while (0)
; /* add k to y's exponent */
239 return y-one;
240 }
241 t = one;
242 if(k<20) {
243 uword hy;
244
245 SET_HIGH_WORD(t, 0x3ff00000 - (0x200000>>k))do { ieee_double_shape_type sh_u; sh_u.value = (t); sh_u.parts
.msw = (0x3ff00000 - (0x200000>>k)); (t) = sh_u.value; }
while (0)
; /* t=1-2^-k */
246 y = t-(e-x);
247 GET_HIGH_WORD(hy, y)do { ieee_double_shape_type gh_u; gh_u.value = (y); (hy) = gh_u
.parts.msw; } while (0)
;
248 SET_HIGH_WORD(y, hy + (k<<20))do { ieee_double_shape_type sh_u; sh_u.value = (y); sh_u.parts
.msw = (hy + (k<<20)); (y) = sh_u.value; } while (0)
; /* add k to y's exponent */
249 } else {
250 uword hy;
251
252 SET_HIGH_WORD(t, (0x3ff-k)<<20)do { ieee_double_shape_type sh_u; sh_u.value = (t); sh_u.parts
.msw = ((0x3ff-k)<<20); (t) = sh_u.value; } while (0)
; /* 2^-k */
253 y = x-(e+t);
254 y += one;
255 GET_HIGH_WORD(hy, y)do { ieee_double_shape_type gh_u; gh_u.value = (y); (hy) = gh_u
.parts.msw; } while (0)
;
256 SET_HIGH_WORD(y, hy + (k<<20))do { ieee_double_shape_type sh_u; sh_u.value = (y); sh_u.parts
.msw = (hy + (k<<20)); (y) = sh_u.value; } while (0)
; /* add k to y's exponent */
257 }
258 }
259 return y;
260}
diff --git a/scan-build/report-27428e.html b/scan-build/report-27428e.html deleted file mode 100644 index f2ce057a..00000000 --- a/scan-build/report-27428e.html +++ /dev/null @@ -1,485 +0,0 @@ - - - -lib/real/kremp2.c - - - - - - - - - - - - - - - - - - - - - - - - - -

Bug Summary

- - - - -
File:real/kremp2.c
Location:line 350, column 18
Description:Assigned value is garbage or undefined
- -

Annotated Source Code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/* @(#)k_rem_pio2.c 1.3 95/01/18 */
2
3/*
4 * Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * The origin source code can be obtained from:
28 * http://www.netlib.org/fdlibm/k_rem_pio2.c
29 *
30 */
31
32/*
33 * ====================================================
34 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
35 *
36 * Developed at SunSoft, a Sun Microsystems, Inc. business.
37 * Permission to use, copy, modify, and distribute this
38 * software is freely granted, provided that this notice
39 * is preserved.
40 * ====================================================
41 */
42
43#include "prim.h"
44#include "math.h"
45
46/*
47 * Constants:
48 * The hexadecimal values are the intended ones for the following
49 * constants. The decimal values may be used, provided that the
50 * compiler will convert from decimal to binary accurately enough
51 * to produce the hexadecimal values shown.
52 */
53
54static const int init_jk[] = {2,3,4,6}; /* initial value for jk */
55
56static const double PIo2[] = {
57 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
58 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
59 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
60 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
61 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
62 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
63 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
64 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
65};
66
67static const double
68zero = 0.0,
69one = 1.0,
70two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
71twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
72
73/**
74 * @brief Kernel reduction function.
75 * @version 1.4
76 * @date 96/03/07
77 * @details
78 * <pre>
79 * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
80 * double x[],y[]; int e0,nx,prec; int ipio2[];
81 *
82 * __kernel_rem_pio2 return the last three digits of N with
83 * y = x - N*pi/2
84 * so that |y| < pi/2.
85 *
86 * The method is to compute the integer (mod 8) and fraction parts of
87 * (2/pi)*x without doing the full multiplication. In general we
88 * skip the part of the product that are known to be a huge integer (
89 * more accurately, = 0 mod 8 ). Thus the number of operations are
90 * independent of the exponent of the input.
91 *
92 * (2/pi) is represented by an array of 24-bit integers in ipio2[].
93 *
94 * Input parameters:
95 * x[] The input value (must be positive) is broken into nx
96 * pieces of 24-bit integers in double precision format.
97 * x[i] will be the i-th 24 bit of x. The scaled exponent
98 * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
99 * match x's up to 24 bits.
100 *
101 * Example of breaking a double positive z into x[0]+x[1]+x[2]:
102 * e0 = ilogb(z)-23
103 * z = scalbn(z,-e0)
104 * for i = 0,1,2
105 * x[i] = floor(z)
106 * z = (z-x[i])*2**24
107 *
108 *
109 * y[] ouput result in an array of double precision numbers.
110 * The dimension of y[] is:
111 * 24-bit precision 1
112 * 53-bit precision 2
113 * 64-bit precision 2
114 * 113-bit precision 3
115 * The actual value is the sum of them. Thus for 113-bit
116 * precison, one may have to do something like:
117 *
118 * long double t,w,r_head, r_tail;
119 * t = (long double)y[2] + (long double)y[1];
120 * w = (long double)y[0];
121 * r_head = t+w;
122 * r_tail = w - (r_head - t);
123 *
124 * e0 The exponent of x[0]
125 *
126 * nx dimension of x[]
127 *
128 * prec an integer indicating the precision:
129 * 0 24 bits (single)
130 * 1 53 bits (double)
131 * 2 64 bits (extended)
132 * 3 113 bits (quad)
133 *
134 * ipio2[]
135 * integer array, contains the (24*i)-th to (24*i+23)-th
136 * bit of 2/pi after binary point. The corresponding
137 * floating value is
138 *
139 * ipio2[i] * 2^(-24(i+1)).
140 *
141 * External function:
142 * double scalbn(), floor();
143 *
144 *
145 * Here is the description of some local variables:
146 *
147 * jk jk+1 is the initial number of terms of ipio2[] needed
148 * in the computation. The recommended value is 2,3,4,
149 * 6 for single, double, extended,and quad.
150 *
151 * jz local integer variable indicating the number of
152 * terms of ipio2[] used.
153 *
154 * jx nx - 1
155 *
156 * jv index for pointing to the suitable ipio2[] for the
157 * computation. In general, we want
158 * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
159 * is an integer. Thus
160 * e0-3-24*jv >= 0 or (e0-3)/24 >= jv
161 * Hence jv = max(0,(e0-3)/24).
162 *
163 * jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
164 *
165 * q[] double array with integral value, representing the
166 * 24-bits chunk of the product of x and 2/pi.
167 *
168 * q0 the corresponding exponent of q[0]. Note that the
169 * exponent for q[i] would be q0-24*i.
170 *
171 * PIo2[] double precision array, obtained by cutting pi/2
172 * into 24 bits chunks.
173 *
174 * f[] ipio2[] in floating point
175 *
176 * iq[] integer array by breaking up q[] in 24-bits chunk.
177 *
178 * fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
179 *
180 * ih integer. If >0 it indicates q[] is >= 0.5, hence
181 * it also indicates the *sign* of the result.
182 *
183 * </pre>
184 * @copyright Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
185 * @license Developed at SunSoft, a Sun Microsystems, Inc. business. Permission
186 * to use, copy, modify, and distribute this software is freely granted,
187 * provided that this notice is preserved.
188 */
189
190int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int *ipio2)
191{
192 int jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
193 double z,fw,f[20],fq[20],q[20];
194
195 /* initialize jk*/
196 jk = init_jk[prec];
197 jp = jk;
198
199 /* determine jx,jv,q0, note that 3>q0 */
200 jx = nx-1;
201 jv = (e0-3)/24;
202 if(jv<0) jv=0;
1
Assuming 'jv' is >= 0
2
Taking false branch
203 q0 = e0-24*(jv+1);
204
205 /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
206 j = jv-jx;
207 m = jx+jk;
208 for(i=0; i<=m; i++,j++) f[i] = (j<0)? zero : (double) ipio2[j];
3
Assuming 'i' is > 'm'
4
Loop condition is false. Execution continues on line 211
209
210 /* compute q[0],q[1],...q[jk] */
211 for (i=0; i<=jk; i++) {
5
Assuming 'i' is > 'jk'
6
Loop condition is false. Execution continues on line 216
212 for(j=0,fw=0.0; j<=jx; j++) fw += x[j]*f[jx+i-j];
213 q[i] = fw;
214 }
215
216 jz = jk;
217recompute:
218 /* distill q[] into iq[] reversingly */
219 for(i=0,j=jz,z=q[jz]; j>0; i++,j--) {
7
Loop condition is false. Execution continues on line 226
21
Assuming 'j' is <= 0
22
Loop condition is false. Execution continues on line 226
220 fw = (double)((int)(twon24* z));
221 iq[i] = (int)(z-two24*fw);
222 z = q[j-1]+fw;
223 }
224
225 /* compute n */
226 z = scalbn(z,q0); /* actual value of z */
227 z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */
228 n = (int) z;
229 z -= (double)n;
230 ih = 0;
231 if(q0>0) { /* need iq[jz-1] to determine n */
8
Assuming 'q0' is <= 0
9
Taking false branch
23
Taking false branch
232 i = (iq[jz-1]>>(24-q0));
233 n += i;
234 iq[jz-1] -= i<<(24-q0);
235 ih = iq[jz-1]>>(23-q0);
236 }
237 else if(q0==0) ih = iq[jz-1]>>23;
10
Assuming 'q0' is not equal to 0
11
Taking false branch
24
Taking false branch
238 else if(z>=0.5) ih=2;
12
Taking false branch
25
Taking true branch
239
240 if(ih>0) { /* q > 0.5 */
13
Taking false branch
26
Taking true branch
241 n += 1;
242 carry = 0;
243 for(i=0; i<jz ; i++) { /* compute 1-q */
27
Loop condition is false. Execution continues on line 252
244 j = iq[i];
245 if(carry==0) {
246 if(j!=0) {
247 carry = 1;
248 iq[i] = 0x1000000- j;
249 }
250 } else iq[i] = 0xffffff - j;
251 }
252 if(q0>0) { /* rare case: chance is 1 in 12 */
28
Taking false branch
253 switch(q0) {
254 case 1:
255 iq[jz-1] &= 0x7fffff;
256 break;
257 case 2:
258 iq[jz-1] &= 0x3fffff;
259 break;
260 }
261 }
262 if(ih==2) {
29
Taking true branch
263 z = one - z;
264 if(carry!=0) z -= scalbn(one,q0);
30
Taking false branch
265 }
266 }
267
268 /* check if recomputation is needed */
269 if(z==zero) {
14
Taking true branch
31
Taking false branch
270 j = 0;
271 for (i=jz-1; i>=jk; i--) j |= iq[i];
15
Loop condition is false. Execution continues on line 272
272 if(j==0) { /* need recomputation */
16
Taking true branch
273 for(k=1; iq[jk-k]==0; k++); /* k = no. of terms needed */
17
Loop condition is true. Entering loop body
18
Loop condition is false. Execution continues on line 275
274
275 for(i=jz+1; i<=jz+k; i++) { /* add q[jz+1] to q[jz+k] */
19
Loop condition is false. Execution continues on line 280
276 f[jx+i] = (double) ipio2[jv+i];
277 for(j=0,fw=0.0; j<=jx; j++) fw += x[j]*f[jx+i-j];
278 q[i] = fw;
279 }
280 jz += k;
281 goto recompute;
20
Control jumps to line 219
282 }
283 }
284
285 /* chop off zero terms */
286 if(z==0.0) {
32
Taking true branch
287 jz -= 1;
288 q0 -= 24;
289 while(iq[jz]==0) {
33
Loop condition is false. Execution continues on line 305
290 jz--;
291 q0-=24;
292 }
293 } else { /* break z into 24-bit if necessary */
294 z = scalbn(z,-q0);
295 if(z>=two24) {
296 fw = (double)((int)(twon24*z));
297 iq[jz] = (int)(z-two24*fw);
298 jz += 1;
299 q0 += 24;
300 iq[jz] = (int) fw;
301 } else iq[jz] = (int) z ;
302 }
303
304 /* convert integer "bit" chunk to floating-point value */
305 fw = scalbn(one,q0);
306 for(i=jz; i>=0; i--) {
34
Loop condition is false. Execution continues on line 312
307 q[i] = fw*(double)iq[i];
308 fw*=twon24;
309 }
310
311 /* compute PIo2[0,...,jp]*q[jz,...,0] */
312 for(i=jz; i>=0; i--) {
35
Loop condition is false. Execution continues on line 318
313 for(fw=0.0,k=0; k<=jp&&k<=jz-i; k++) fw += PIo2[k]*q[i+k];
314 fq[jz-i] = fw;
315 }
316
317 /* compress fq[] into y[] */
318 switch(prec) {
36
Control jumps to 'case 3:' at line 333
319 case 0:
320 fw = 0.0;
321 for (i=jz; i>=0; i--) fw += fq[i];
322 y[0] = (ih==0)? fw: -fw;
323 break;
324 case 1:
325 case 2:
326 fw = 0.0;
327 for (i=jz; i>=0; i--) fw += fq[i];
328 y[0] = (ih==0)? fw: -fw;
329 fw = fq[0]-fw;
330 for (i=1; i<=jz; i++) fw += fq[i];
331 y[1] = (ih==0)? fw: -fw;
332 break;
333 case 3: /* painful */
334 for (i=jz; i>0; i--) {
37
Loop condition is false. Execution continues on line 339
335 fw = fq[i-1]+fq[i];
336 fq[i] += fq[i-1]-fw;
337 fq[i-1] = fw;
338 }
339 for (i=jz; i>1; i--) {
38
Loop condition is false. Execution continues on line 344
340 fw = fq[i-1]+fq[i];
341 fq[i] += fq[i-1]-fw;
342 fq[i-1] = fw;
343 }
344 for (fw=0.0,i=jz; i>=2; i--) fw += fq[i];
39
Loop condition is false. Execution continues on line 345
345 if(ih==0) {
40
Taking false branch
346 y[0] = fq[0];
347 y[1] = fq[1];
348 y[2] = fw;
349 } else {
350 y[0] = -fq[0];
41
Assigned value is garbage or undefined
351 y[1] = -fq[1];
352 y[2] = -fw;
353 }
354 }
355 return n&7;
356}
diff --git a/scan-build/report-27e74a.html b/scan-build/report-27e74a.html deleted file mode 100644 index bf4fe79b..00000000 --- a/scan-build/report-27e74a.html +++ /dev/null @@ -1,1291 +0,0 @@ - - - -lib/dconv/dragon4.cpp - - - - - - - - - - - - - - - - - - - - - - - - - -

Bug Summary

- - - - -
File:dconv/dragon4.cpp
Location:line 403, column 38
Description:The left operand of '*' is a garbage value
- -

Annotated Source Code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/******************************************************************************
2 Copyright (c) 2014 Ryan Juckett
3 http://www.ryanjuckett.com/
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20
21 3. This notice may not be removed or altered from any source
22 distribution.
23*******************************************************************************
24 Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
25 All rights reserved.
26
27 Redistribution and use in source and binary forms, with or without
28 modification, are permitted provided that the following conditions
29 are met:
30 1. Redistributions of source code must retain the above copyright
31 notice, this list of conditions and the following disclaimer.
32
33 2. Redistributions in binary form must reproduce the above copyright
34 notice, this list of conditions and the following disclaimer in the
35 documentation and/or other materials provided with the distribution.
36
37 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
38 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
40 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
41 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
46 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47
48 The origin source code can be obtained from:
49 http://www.ryanjuckett.com/
50
51******************************************************************************/
52
53#include "math.h"
54#include "dmath.h"
55#include "dragon4.h"
56
57//******************************************************************************
58// Maximum number of 32 bit blocks needed in high precision arithmetic
59// to print out 64 bit IEEE floating point values.
60//******************************************************************************
61const tU32 c_BigInt_MaxBlocks = 35;
62
63//******************************************************************************
64// This structure stores a high precision unsigned integer. It uses a buffer
65// of 32 bit integer blocks along with a length. The lowest bits of the integer
66// are stored at the start of the buffer and the length is set to the minimum
67// value that contains the integer. Thus, there are never any zero blocks at the
68// end of the buffer.
69//******************************************************************************
70struct tBigInt
71{
72 // Copy integer
73 tBigInt & operator=(const tBigInt &rhs)
74 {
75 tU32 length = rhs.m_length;
76 tU32 * pLhsCur = m_blocks;
77 for (const tU32 *pRhsCur = rhs.m_blocks, *pRhsEnd = pRhsCur + length;
78 pRhsCur != pRhsEnd;
79 ++pLhsCur, ++pRhsCur)
80 {
81 *pLhsCur = *pRhsCur;
82 }
83 m_length = length;
84 return *this;
85 }
86
87 // Data accessors
88 tU32 GetLength() const {
89 return m_length;
90 }
91 tU32 GetBlock(tU32 idx) const {
92 return m_blocks[idx];
93 }
94
95 // Zero helper functions
96 void SetZero() {
97 m_length = 0;
98 }
99 tB IsZero() const {
100 return m_length == 0;
101 }
102
103 // Basic type accessors
104 void SetU64(tU64 val)
105 {
106 if (val > 0xFFFFFFFF)
107 {
108 m_blocks[0] = val & 0xFFFFFFFF;
109 m_blocks[1] = (val >> 32) & 0xFFFFFFFF;
110 m_length = 2;
111 }
112 else if (val != 0)
113 {
114 m_blocks[0] = val & 0xFFFFFFFF;
115 m_length = 1;
116 }
117 else
118 {
119 m_length = 0;
120 }
121 }
122
123 void SetU32(tU32 val)
124 {
125 if (val != 0)
126 {
127 m_blocks[0] = val;
128 m_length = (val != 0);
129 }
130 else
131 {
132 m_length = 0;
133 }
134 }
135
136 tU32 GetU32() const {
137 return (m_length == 0) ? 0 : m_blocks[0];
138 }
139
140 // Member data
141 tU32 m_length;
142 tU32 m_blocks[c_BigInt_MaxBlocks];
143};
144
145//******************************************************************************
146// Returns 0 if (lhs = rhs), negative if (lhs < rhs), positive if (lhs > rhs)
147//******************************************************************************
148static tS32 BigInt_Compare(const tBigInt & lhs, const tBigInt & rhs)
149{
150 // A bigger length implies a bigger number.
151 tS32 lengthDiff = lhs.m_length - rhs.m_length;
152 if (lengthDiff != 0)
153 return lengthDiff;
154
155 // Compare blocks one by one from high to low.
156 for (tS32 i = lhs.m_length - 1; i >= 0; --i)
157 {
158 if (lhs.m_blocks[i] == rhs.m_blocks[i])
159 continue;
160 else if (lhs.m_blocks[i] > rhs.m_blocks[i])
161 return 1;
162 else
163 return -1;
164 }
165
166 // no blocks differed
167 return 0;
168}
169
170//******************************************************************************
171// result = lhs + rhs
172//******************************************************************************
173static void BigInt_Add(tBigInt * pResult, const tBigInt & lhs, const tBigInt & rhs)
174{
175 // determine which operand has the smaller length
176 const tBigInt * pLarge;
177 const tBigInt * pSmall;
178 if (lhs.m_length < rhs.m_length)
179 {
180 pSmall = &lhs;
181 pLarge = &rhs;
182 }
183 else
184 {
185 pSmall = &rhs;
186 pLarge = &lhs;
187 }
188
189 const tU32 largeLen = pLarge->m_length;
190 const tU32 smallLen = pSmall->m_length;
191
192 // The output will be at least as long as the largest input
193 pResult->m_length = largeLen;
194
195 // Add each block and add carry the overflow to the next block
196 tU64 carry = 0;
197 const tU32 * pLargeCur = pLarge->m_blocks;
198 const tU32 * pLargeEnd = pLargeCur + largeLen;
199 const tU32 * pSmallCur = pSmall->m_blocks;
200 const tU32 * pSmallEnd = pSmallCur + smallLen;
201 tU32 * pResultCur = pResult->m_blocks;
202 while (pSmallCur != pSmallEnd)
203 {
204 tU64 sum = carry + (tU64)(*pLargeCur) + (tU64)(*pSmallCur);
205 carry = sum >> 32;
206 (*pResultCur) = sum & 0xFFFFFFFF;
207 ++pLargeCur;
208 ++pSmallCur;
209 ++pResultCur;
210 }
211
212 // Add the carry to any blocks that only exist in the large operand
213 while (pLargeCur != pLargeEnd)
214 {
215 tU64 sum = carry + (tU64)(*pLargeCur);
216 carry = sum >> 32;
217 (*pResultCur) = sum & 0xFFFFFFFF;
218 ++pLargeCur;
219 ++pResultCur;
220 }
221
222 // If there's still a carry, append a new block
223 if (carry != 0)
224 {
225 RJ_ASSERT(carry == 1);
226 RJ_ASSERT((tU32)(pResultCur - pResult->m_blocks) == largeLen && (largeLen < c_BigInt_MaxBlocks));
227 *pResultCur = 1;
228 pResult->m_length = largeLen + 1;
229 }
230 else
231 {
232 pResult->m_length = largeLen;
233 }
234}
235
236//******************************************************************************
237// result = lhs * rhs
238//******************************************************************************
239static void BigInt_Multiply(tBigInt * pResult, const tBigInt &lhs, const tBigInt &rhs)
240{
241 RJ_ASSERT( pResult != &lhs && pResult != &rhs );
242
243 // determine which operand has the smaller length
244 const tBigInt * pLarge;
245 const tBigInt * pSmall;
246 if (lhs.m_length < rhs.m_length)
247 {
248 pSmall = &lhs;
249 pLarge = &rhs;
250 }
251 else
252 {
253 pSmall = &rhs;
254 pLarge = &lhs;
255 }
256
257 // set the maximum possible result length
258 tU32 maxResultLen = pLarge->m_length + pSmall->m_length;
259 RJ_ASSERT( maxResultLen <= c_BigInt_MaxBlocks );
260
261 // clear the result data
262 for(tU32 * pCur = pResult->m_blocks, *pEnd = pCur + maxResultLen; pCur != pEnd; ++pCur)
263 *pCur = 0;
264
265 // perform standard long multiplication
266 const tU32 *pLargeBeg = pLarge->m_blocks;
267 const tU32 *pLargeEnd = pLargeBeg + pLarge->m_length;
268
269 // for each small block
270 tU32 *pResultStart = pResult->m_blocks;
271 for(const tU32 *pSmallCur = pSmall->m_blocks, *pSmallEnd = pSmallCur + pSmall->m_length;
272 pSmallCur != pSmallEnd;
273 ++pSmallCur, ++pResultStart)
274 {
275 // if non-zero, multiply against all the large blocks and add into the result
276 const tU32 multiplier = *pSmallCur;
277 if (multiplier != 0)
278 {
279 const tU32 *pLargeCur = pLargeBeg;
280 tU32 *pResultCur = pResultStart;
281 tU64 carry = 0;
282 do
283 {
284 tU64 product = (*pResultCur) + (*pLargeCur)*(tU64)multiplier + carry;
285 carry = product >> 32;
286 *pResultCur = product & 0xFFFFFFFF;
287 ++pLargeCur;
288 ++pResultCur;
289 } while(pLargeCur != pLargeEnd);
290
291 RJ_ASSERT(pResultCur < pResult->m_blocks + maxResultLen);
292 *pResultCur = (tU32)(carry & 0xFFFFFFFF);
293 }
294 }
295
296 // check if the terminating block has no set bits
297 if (maxResultLen > 0 && pResult->m_blocks[maxResultLen - 1] == 0)
298 pResult->m_length = maxResultLen-1;
299 else
300 pResult->m_length = maxResultLen;
301}
302
303//******************************************************************************
304// result = lhs * rhs
305//******************************************************************************
306static void BigInt_Multiply(tBigInt * pResult, const tBigInt & lhs, tU32 rhs)
307{
308 // perform long multiplication
309 tU32 carry = 0;
310 tU32 *pResultCur = pResult->m_blocks;
311 const tU32 *pLhsCur = lhs.m_blocks;
312 const tU32 *pLhsEnd = lhs.m_blocks + lhs.m_length;
313 for ( ; pLhsCur != pLhsEnd; ++pLhsCur, ++pResultCur )
314 {
315 tU64 product = (tU64)(*pLhsCur) * rhs + carry;
316 *pResultCur = (tU32)(product & 0xFFFFFFFF);
317 carry = product >> 32;
318 }
319
320 // if there is a remaining carry, grow the array
321 if (carry != 0)
322 {
323 // grow the array
324 RJ_ASSERT(lhs.m_length + 1 <= c_BigInt_MaxBlocks);
325 *pResultCur = (tU32)carry;
326 pResult->m_length = lhs.m_length + 1;
327 }
328 else
329 {
330 pResult->m_length = lhs.m_length;
331 }
332}
333
334//******************************************************************************
335// result = in * 2
336//******************************************************************************
337static void BigInt_Multiply2(tBigInt * pResult, const tBigInt &in)
338{
339 // shift all the blocks by one
340 tU32 carry = 0;
341
342 tU32 *pResultCur = pResult->m_blocks;
343 const tU32 *pLhsCur = in.m_blocks;
344 const tU32 *pLhsEnd = in.m_blocks + in.m_length;
345 for ( ; pLhsCur != pLhsEnd; ++pLhsCur, ++pResultCur )
346 {
347 tU32 cur = *pLhsCur;
348 *pResultCur = (cur << 1) | carry;
349 carry = cur >> 31;
350 }
351
352 if (carry != 0)
353 {
354 // grow the array
355 RJ_ASSERT(in.m_length + 1 <= c_BigInt_MaxBlocks);
356 *pResultCur = carry;
357 pResult->m_length = in.m_length + 1;
358 }
359 else
360 {
361 pResult->m_length = in.m_length;
362 }
363}
364
365//******************************************************************************
366// result = result * 2
367//******************************************************************************
368static void BigInt_Multiply2(tBigInt * pResult)
369{
370 // shift all the blocks by one
371 tU32 carry = 0;
372
373 tU32 *pCur = pResult->m_blocks;
374 tU32 *pEnd = pResult->m_blocks + pResult->m_length;
375 for ( ; pCur != pEnd; ++pCur )
376 {
377 tU32 cur = *pCur;
378 *pCur = (cur << 1) | carry;
379 carry = cur >> 31;
380 }
381
382 if (carry != 0)
383 {
384 // grow the array
385 RJ_ASSERT(pResult->m_length + 1 <= c_BigInt_MaxBlocks);
386 *pCur = carry;
387 ++pResult->m_length;
388 }
389}
390
391//******************************************************************************
392// result = result * 10
393//******************************************************************************
394static void BigInt_Multiply10(tBigInt * pResult)
395{
396 // multiply all the blocks
397 tU64 carry = 0;
398
399 tU32 *pCur = pResult->m_blocks;
400 tU32 *pEnd = pResult->m_blocks + pResult->m_length;
401 for ( ; pCur != pEnd; ++pCur )
14
Loop condition is false. Execution continues on line 408
39
Loop condition is true. Entering loop body
40
Assuming 'pCur' is not equal to 'pEnd'
41
Loop condition is true. Entering loop body
402 {
403 tU64 product = (tU64)(*pCur) * 10ull + carry;
42
The left operand of '*' is a garbage value
404 (*pCur) = (tU32)(product & 0xFFFFFFFF);
405 carry = product >> 32;
406 }
407
408 if (carry != 0)
15
Taking false branch
409 {
410 // grow the array
411 RJ_ASSERT(pResult->m_length + 1 <= c_BigInt_MaxBlocks);
412 *pCur = (tU32)carry;
413 ++pResult->m_length;
414 }
415}
416
417//******************************************************************************
418//******************************************************************************
419static tU32 g_PowerOf10_U32[] =
420{
421 1, // 10 ^ 0
422 10, // 10 ^ 1
423 100, // 10 ^ 2
424 1000, // 10 ^ 3
425 10000, // 10 ^ 4
426 100000, // 10 ^ 5
427 1000000, // 10 ^ 6
428 10000000, // 10 ^ 7
429};
430
431//******************************************************************************
432// Note: This has a lot of wasted space in the big integer structures of the
433// early table entries. It wouldn't be terribly hard to make the multiply
434// function work on integer pointers with an array length instead of
435// the tBigInt struct which would allow us to store a minimal amount of
436// data here.
437//******************************************************************************
438static tBigInt g_PowerOf10_Big[] =
439{
440 // 10 ^ 8
441 { 1, { 100000000 } },
442 // 10 ^ 16
443 { 2, { 0x6fc10000, 0x002386f2 } },
444 // 10 ^ 32
445 { 4, { 0x00000000, 0x85acef81, 0x2d6d415b, 0x000004ee, } },
446 // 10 ^ 64
447 { 7, { 0x00000000, 0x00000000, 0xbf6a1f01, 0x6e38ed64, 0xdaa797ed, 0xe93ff9f4, 0x00184f03, } },
448 // 10 ^ 128
449 { 14, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x2e953e01, 0x03df9909, 0x0f1538fd,
450 0x2374e42f, 0xd3cff5ec, 0xc404dc08, 0xbccdb0da, 0xa6337f19, 0xe91f2603, 0x0000024e,
451 }
452 },
453 // 10 ^ 256
454 { 27, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
455 0x00000000, 0x982e7c01, 0xbed3875b, 0xd8d99f72, 0x12152f87, 0x6bde50c6, 0xcf4a6e70,
456 0xd595d80f, 0x26b2716e, 0xadc666b0, 0x1d153624, 0x3c42d35a, 0x63ff540e, 0xcc5573c0,
457 0x65f9ef17, 0x55bc28f2, 0x80dcc7f7, 0xf46eeddc, 0x5fdcefce, 0x000553f7,
458 }
459 }
460};
461
462//******************************************************************************
463// result = 10^exponent
464//******************************************************************************
465static void BigInt_Pow10(tBigInt * pResult, tU32 exponent)
466{
467 // make sure the exponent is within the bounds of the lookup table data
468 RJ_ASSERT(exponent < 512);
469
470 // create two temporary values to reduce large integer copy operations
471 tBigInt temp1;
472 tBigInt temp2;
473 tBigInt *pCurTemp = &temp1;
474 tBigInt *pNextTemp = &temp2;
475
476 // initialize the result by looking up a 32-bit power of 10 corresponding to the first 3 bits
477 tU32 smallExponent = exponent & 0x7;
478 pCurTemp->SetU32(g_PowerOf10_U32[smallExponent]);
479
480 // remove the low bits that we used for the 32-bit lookup table
481 exponent >>= 3;
482 tU32 tableIdx = 0;
483
484 // while there are remaining bits in the exponent to be processed
485 while (exponent != 0)
486 {
487 // if the current bit is set, multiply it with the corresponding power of 10
488 if(exponent & 1)
489 {
490 // multiply into the next temporary
491 BigInt_Multiply( pNextTemp, *pCurTemp, g_PowerOf10_Big[tableIdx] );
492
493 // swap to the next temporary
494 tBigInt * pSwap = pCurTemp;
495 pCurTemp = pNextTemp;
496 pNextTemp = pSwap;
497 }
498
499 // advance to the next bit
500 ++tableIdx;
501 exponent >>= 1;
502 }
503
504 // output the result
505 *pResult = *pCurTemp;
506}
507
508//******************************************************************************
509// result = in * 10^exponent
510//******************************************************************************
511static void BigInt_MultiplyPow10(tBigInt * pResult, const tBigInt & in, tU32 exponent)
512{
513 // make sure the exponent is within the bounds of the lookup table data
514 RJ_ASSERT(exponent < 512);
515
516 // create two temporary values to reduce large integer copy operations
517 tBigInt temp1;
518 tBigInt temp2;
519 tBigInt *pCurTemp = &temp1;
520 tBigInt *pNextTemp = &temp2;
521
522 // initialize the result by looking up a 32-bit power of 10 corresponding to the first 3 bits
523 tU32 smallExponent = exponent & 0x7;
524 if (smallExponent != 0)
525 {
526 BigInt_Multiply( pCurTemp, in, g_PowerOf10_U32[smallExponent] );
527 }
528 else
529 {
530 *pCurTemp = in;
531 }
532
533 // remove the low bits that we used for the 32-bit lookup table
534 exponent >>= 3;
535 tU32 tableIdx = 0;
536
537 // while there are remaining bits in the exponent to be processed
538 while (exponent != 0)
539 {
540 // if the current bit is set, multiply it with the corresponding power of 10
541 if(exponent & 1)
542 {
543 // multiply into the next temporary
544 BigInt_Multiply( pNextTemp, *pCurTemp, g_PowerOf10_Big[tableIdx] );
545
546 // swap to the next temporary
547 tBigInt * pSwap = pCurTemp;
548 pCurTemp = pNextTemp;
549 pNextTemp = pSwap;
550 }
551
552 // advance to the next bit
553 ++tableIdx;
554 exponent >>= 1;
555 }
556
557 // output the result
558 *pResult = *pCurTemp;
559}
560
561//******************************************************************************
562// result = 2^exponent
563//******************************************************************************
564static inline void BigInt_Pow2(tBigInt * pResult, tU32 exponent)
565{
566 tU32 blockIdx = exponent / 32;
567 RJ_ASSERT( blockIdx < c_BigInt_MaxBlocks );
568
569 for ( tU32 i = 0; i <= blockIdx; ++i)
570 pResult->m_blocks[i] = 0;
571
572 pResult->m_length = blockIdx + 1;
573
574 tU32 bitIdx = (exponent % 32);
575 pResult->m_blocks[blockIdx] |= (1 << bitIdx);
576}
577
578//******************************************************************************
579// This function will divide two large numbers under the assumption that the
580// result is within the range [0,10) and the input numbers have been shifted
581// to satisfy:
582// - The highest block of the divisor is greater than or equal to 8 such that
583// there is enough precision to make an accurate first guess at the quotient.
584// - The highest block of the divisor is less than the maximum value on an
585// unsigned 32-bit integer such that we can safely increment without overflow.
586// - The dividend does not contain more blocks than the divisor such that we
587// can estimate the quotient by dividing the equivalently placed high blocks.
588//
589// quotient = floor(dividend / divisor)
590// remainder = dividend - quotient*divisor
591//
592// pDividend is updated to be the remainder and the quotient is returned.
593//******************************************************************************
594static tU32 BigInt_DivideWithRemainder_MaxQuotient9(tBigInt * pDividend, const tBigInt & divisor)
595{
596 // Check that the divisor has been correctly shifted into range and that it is not
597 // smaller than the dividend in length.
598 RJ_ASSERT( !divisor.IsZero() &&
599 divisor.m_blocks[divisor.m_length-1] >= 8 &&
600 divisor.m_blocks[divisor.m_length-1] < 0xFFFFFFFF &&
601 pDividend->m_length <= divisor.m_length );
602
603 // If the dividend is smaller than the divisor, the quotient is zero and the divisor is already
604 // the remainder.
605 tU32 length = divisor.m_length;
606 if (pDividend->m_length < divisor.m_length)
34
Taking true branch
607 return 0;
608
609 const tU32 * pFinalDivisorBlock = divisor.m_blocks + length - 1;
610 tU32 * pFinalDividendBlock = pDividend->m_blocks + length - 1;
611
612 // Compute an estimated quotient based on the high block value. This will either match the actual quotient or
613 // undershoot by one.
614 tU32 quotient = *pFinalDividendBlock / (*pFinalDivisorBlock + 1);
615 RJ_ASSERT(quotient <= 9);
616
617 // Divide out the estimated quotient
618 if (quotient != 0)
619 {
620 // dividend = dividend - divisor*quotient
621 const tU32 *pDivisorCur = divisor.m_blocks;
622 tU32 *pDividendCur = pDividend->m_blocks;
623
624 tU64 borrow = 0;
625 tU64 carry = 0;
626 do
627 {
628 tU64 product = (tU64)*pDivisorCur * (tU64)quotient + carry;
629 carry = product >> 32;
630
631 tU64 difference = (tU64)*pDividendCur - (product & 0xFFFFFFFF) - borrow;
632 borrow = (difference >> 32) & 1;
633
634 *pDividendCur = difference & 0xFFFFFFFF;
635
636 ++pDivisorCur;
637 ++pDividendCur;
638 } while(pDivisorCur <= pFinalDivisorBlock);
639
640 // remove all leading zero blocks from dividend
641 while (length > 0 && pDividend->m_blocks[length - 1] == 0)
642 --length;
643
644 pDividend->m_length = length;
645 }
646
647 // If the dividend is still larger than the divisor, we overshot our estimate quotient. To correct,
648 // we increment the quotient and subtract one more divisor from the dividend.
649 if ( BigInt_Compare(*pDividend, divisor) >= 0 )
650 {
651 ++quotient;
652
653 // dividend = dividend - divisor
654 const tU32 *pDivisorCur = divisor.m_blocks;
655 tU32 *pDividendCur = pDividend->m_blocks;
656
657 tU64 borrow = 0;
658 do
659 {
660 tU64 difference = (tU64)*pDividendCur - (tU64)*pDivisorCur - borrow;
661 borrow = (difference >> 32) & 1;
662
663 *pDividendCur = difference & 0xFFFFFFFF;
664
665 ++pDivisorCur;
666 ++pDividendCur;
667 } while(pDivisorCur <= pFinalDivisorBlock);
668
669 // remove all leading zero blocks from dividend
670 while (length > 0 && pDividend->m_blocks[length - 1] == 0)
671 --length;
672
673 pDividend->m_length = length;
674 }
675
676 return quotient;
677}
678
679//******************************************************************************
680// result = result << shift
681//******************************************************************************
682static void BigInt_ShiftLeft(tBigInt * pResult, tU32 shift)
683{
684 RJ_ASSERT( shift != 0 );
685
686 tU32 shiftBlocks = shift / 32;
687 tU32 shiftBits = shift % 32;
688
689 // process blocks high to low so that we can safely process in place
690 const tU32 * pInBlocks = pResult->m_blocks;
691 tS32 inLength = pResult->m_length;
692 RJ_ASSERT( inLength + shiftBlocks < c_BigInt_MaxBlocks );
693
694 // check if the shift is block aligned
695 if (shiftBits == 0)
25
Taking false branch
696 {
697 // copy blcoks from high to low
698 for (tU32 * pInCur = pResult->m_blocks + inLength, *pOutCur = pInCur + shiftBlocks;
699 pInCur >= pInBlocks;
700 --pInCur, --pOutCur)
701 {
702 *pOutCur = *pInCur;
703 }
704
705 // zero the remaining low blocks
706 for ( tU32 i = 0; i < shiftBlocks; ++i)
707 pResult->m_blocks[i] = 0;
708
709 pResult->m_length += shiftBlocks;
710 }
711 // else we need to shift partial blocks
712 else
713 {
714 tS32 inBlockIdx = inLength - 1;
715 tU32 outBlockIdx = inLength + shiftBlocks;
716
717 // set the length to hold the shifted blocks
718 RJ_ASSERT( outBlockIdx < c_BigInt_MaxBlocks );
719 pResult->m_length = outBlockIdx + 1;
720
721 // output the initial blocks
722 const tU32 lowBitsShift = (32 - shiftBits);
723 tU32 highBits = 0;
724 tU32 block = pResult->m_blocks[inBlockIdx];
725 tU32 lowBits = block >> lowBitsShift;
726 while ( inBlockIdx > 0 )
26
Loop condition is false. Execution continues on line 740
727 {
728 pResult->m_blocks[outBlockIdx] = highBits | lowBits;
729 highBits = block << shiftBits;
730
731 --inBlockIdx;
732 --outBlockIdx;
733
734 block = pResult->m_blocks[inBlockIdx];
735 lowBits = block >> lowBitsShift;
736 }
737
738 // output the final blocks
739 RJ_ASSERT( outBlockIdx == shiftBlocks + 1 );
740 pResult->m_blocks[outBlockIdx] = highBits | lowBits;
741 pResult->m_blocks[outBlockIdx-1] = block << shiftBits;
742
743 // zero the remaining low blocks
744 for ( tU32 i = 0; i < shiftBlocks; ++i)
27
Loop condition is false. Execution continues on line 748
745 pResult->m_blocks[i] = 0;
746
747 // check if the terminating block has no set bits
748 if (pResult->m_blocks[pResult->m_length - 1] == 0)
28
Taking false branch
749 --pResult->m_length;
750 }
751}
752
753//******************************************************************************
754// This is an implementation the Dragon4 algorithm to convert a binary number
755// in floating point format to a decimal number in string format. The function
756// returns the number of digits written to the output buffer and the output is
757// not NUL terminated.
758//
759// The floating point input value is (mantissa * 2^exponent).
760//
761// See the following papers for more information on the algorithm:
762// "How to Print Floating-Point Numbers Accurately"
763// Steele and White
764// http://kurtstephens.com/files/p372-steele.pdf
765// "Printing Floating-Point Numbers Quickly and Accurately"
766// Burger and Dybvig
767// http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.4656&rep=rep1&type=pdf
768//******************************************************************************
769tU32 Dragon4
770(
771 const tU64 mantissa, // value significand
772 const tS32 exponent, // value exponent in base 2
773 const tU32 mantissaHighBitIdx, // index of the highest set mantissa bit
774 const tB hasUnequalMargins, // is the high margin twice as large as the low margin
775 const tCutoffMode cutoffMode, // how to determine output length
776 tU32 cutoffNumber, // parameter to the selected cutoffMode
777 tC8 * pOutBuffer, // buffer to output into
778 tU32 bufferSize, // maximum characters that can be printed to pOutBuffer
779 tS32 * pOutExponent // the base 10 exponent of the first digit
780)
781{
782 tC8 * pCurDigit = pOutBuffer;
783
784 RJ_ASSERT( bufferSize > 0 );
785
786 // if the mantissa is zero, the value is zero regardless of the exponent
787 if (mantissa == 0)
1
Assuming 'mantissa' is not equal to 0
2
Taking false branch
788 {
789 *pCurDigit = '0';
790 *pOutExponent = 0;
791 return 1;
792 }
793
794 // compute the initial state in integral form such that
795 // value = scaledValue / scale
796 // marginLow = scaledMarginLow / scale
797 tBigInt scale; // positive scale applied to value and margin such that they can be
798 // represented as whole numbers
799 tBigInt scaledValue; // scale * mantissa
800 tBigInt scaledMarginLow; // scale * 0.5 * (distance between this floating-point number and its
801 // immediate lower value)
802
803 // For normalized IEEE floating point values, each time the exponent is incremented the margin also
804 // doubles. That creates a subset of transition numbers where the high margin is twice the size of
805 // the low margin.
806 tBigInt * pScaledMarginHigh;
807 tBigInt optionalMarginHigh;
808
809 if ( hasUnequalMargins )
3
Assuming 'hasUnequalMargins' is 0
4
Taking false branch
810 {
811 // if we have no fractional component
812 if (exponent > 0)
813 {
814 // 1) Expand the input value by multiplying out the mantissa and exponent. This represents
815 // the input value in its whole number representation.
816 // 2) Apply an additional scale of 2 such that later comparisons against the margin values
817 // are simplified.
818 // 3) Set the margin value to the lowest mantissa bit's scale.
819
820 // scaledValue = 2 * 2 * mantissa*2^exponent
821 scaledValue.SetU64( 4 * mantissa );
822 BigInt_ShiftLeft( &scaledValue, exponent );
823
824 // scale = 2 * 2 * 1
825 scale.SetU32( 4 );
826
827 // scaledMarginLow = 2 * 2^(exponent-1)
828 BigInt_Pow2( &scaledMarginLow, exponent );
829
830 // scaledMarginHigh = 2 * 2 * 2^(exponent-1)
831 BigInt_Pow2( &optionalMarginHigh, exponent + 1 );
832 }
833 // else we have a fractional exponent
834 else
835 {
836 // In order to track the mantissa data as an integer, we store it as is with a large scale
837
838 // scaledValue = 2 * 2 * mantissa
839 scaledValue.SetU64( 4 * mantissa );
840
841 // scale = 2 * 2 * 2^(-exponent)
842 BigInt_Pow2(&scale, -exponent + 2 );
843
844 // scaledMarginLow = 2 * 2^(-1)
845 scaledMarginLow.SetU32( 1 );
846
847 // scaledMarginHigh = 2 * 2 * 2^(-1)
848 optionalMarginHigh.SetU32( 2 );
849 }
850
851 // the high and low margins are different
852 pScaledMarginHigh = &optionalMarginHigh;
853 }
854 else
855 {
856 // if we have no fractional component
857 if (exponent > 0)
5
Assuming 'exponent' is <= 0
6
Taking false branch
858 {
859 // 1) Expand the input value by multiplying out the mantissa and exponent. This represents
860 // the input value in its whole number representation.
861 // 2) Apply an additional scale of 2 such that later comparisons against the margin values
862 // are simplified.
863 // 3) Set the margin value to the lowest mantissa bit's scale.
864
865 // scaledValue = 2 * mantissa*2^exponent
866 scaledValue.SetU64( 2 * mantissa );
867 BigInt_ShiftLeft( &scaledValue, exponent );
868
869 // scale = 2 * 1
870 scale.SetU32( 2 );
871
872 // scaledMarginLow = 2 * 2^(exponent-1)
873 BigInt_Pow2( &scaledMarginLow, exponent );
874 }
875 // else we have a fractional exponent
876 else
877 {
878 // In order to track the mantissa data as an integer, we store it as is with a large scale
879
880 // scaledValue = 2 * mantissa
881 scaledValue.SetU64( 2 * mantissa );
882
883 // scale = 2 * 2^(-exponent)
884 BigInt_Pow2(&scale, -exponent + 1 );
885
886 // scaledMarginLow = 2 * 2^(-1)
887 scaledMarginLow.SetU32( 1 );
888 }
889
890 // the high and low margins are equal
891 pScaledMarginHigh = &scaledMarginLow;
892 }
893
894 // Compute an estimate for digitExponent that will be correct or undershoot by one.
895 // This optimization is based on the paper "Printing Floating-Point Numbers Quickly and Accurately"
896 // by Burger and Dybvig http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.4656&rep=rep1&type=pdf
897 // We perform an additional subtraction of 0.69 to increase the frequency of a failed estimate
898 // because that lets us take a faster branch in the code. 0.69 is chosen because 0.69 + log10(2) is
899 // less than one by a reasonable epsilon that will account for any floating point error.
900 //
901 // We want to set digitExponent to floor(log10(v)) + 1
902 // v = mantissa*2^exponent
903 // log2(v) = log2(mantissa) + exponent;
904 // log10(v) = log2(v) * log10(2)
905 // floor(log2(v)) = mantissaHighBitIdx + exponent;
906 // log10(v) - log10(2) < (mantissaHighBitIdx + exponent) * log10(2) <= log10(v)
907 // log10(v) < (mantissaHighBitIdx + exponent) * log10(2) + log10(2) <= log10(v) + log10(2)
908 // floor( log10(v) ) < ceil( (mantissaHighBitIdx + exponent) * log10(2) ) <= floor( log10(v) ) + 1
909 const tF64 log10_2 = 0.30102999566398119521373889472449;
910 tS32 digitExponent = (tS32)(ceil(tF64((tS32)mantissaHighBitIdx + exponent) * log10_2 - 0.69));
911
912 // if the digit exponent is smaller than the smallest desired digit for fractional cutoff,
913 // pull the digit back into legal range at which point we will round to the appropriate value.
914 // Note that while our value for digitExponent is still an estimate, this is safe because it
915 // only increases the number. This will either correct digitExponent to an accurate value or it
916 // will clamp it above the accurate value.
917 if (cutoffMode == CutoffMode_FractionLength && digitExponent <= -(tS32)cutoffNumber)
7
Assuming 'cutoffMode' is not equal to CutoffMode_FractionLength
918 {
919 digitExponent = -(tS32)cutoffNumber + 1;
920 }
921
922 // Divide value by 10^digitExponent.
923 if (digitExponent > 0)
8
Assuming 'digitExponent' is <= 0
9
Taking false branch
924 {
925 // The exponent is positive creating a division so we multiply up the scale.
926 tBigInt temp;
927 BigInt_MultiplyPow10( &temp, scale, digitExponent );
928 scale = temp;
929 }
930 else if (digitExponent < 0)
10
Assuming 'digitExponent' is >= 0
11
Taking false branch
931 {
932 // The exponent is negative creating a multiplication so we multiply up the scaledValue,
933 // scaledMarginLow and scaledMarginHigh.
934 tBigInt pow10;
935 BigInt_Pow10( &pow10, -digitExponent);
936
937 tBigInt temp;
938 BigInt_Multiply( &temp, scaledValue, pow10);
939 scaledValue = temp;
940
941 BigInt_Multiply( &temp, scaledMarginLow, pow10);
942 scaledMarginLow = temp;
943
944 if (pScaledMarginHigh != &scaledMarginLow)
945 BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow );
946 }
947
948 // If (value + marginHigh) >= 1, our estimate for digitExponent was too low
949 tBigInt scaledValueHigh;
950 BigInt_Add( &scaledValueHigh, scaledValue, *pScaledMarginHigh );
951 if( BigInt_Compare(scaledValueHigh,scale) >= 0 )
12
Taking false branch
952 {
953 // The exponent estimate was incorrect.
954 // Increment the exponent and don't perform the premultiply needed
955 // for the first loop iteration.
956 digitExponent = digitExponent + 1;
957 }
958 else
959 {
960 // The exponent estimate was correct.
961 // Multiply larger by the output base to prepare for the first loop iteration.
962 BigInt_Multiply10( &scaledValue );
13
Calling 'BigInt_Multiply10'
16
Returning from 'BigInt_Multiply10'
963 BigInt_Multiply10( &scaledMarginLow );
964 if (pScaledMarginHigh != &scaledMarginLow)
17
Taking false branch
965 BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow );
966 }
967
968 // Compute the cutoff exponent (the exponent of the final digit to print).
969 // Default to the maximum size of the output buffer.
970 tS32 cutoffExponent = digitExponent - bufferSize;
971 switch(cutoffMode)
18
Control jumps to 'case CutoffMode_TotalLength:' at line 978
972 {
973 // print digits until we pass the accuracy margin limits or buffer size
974 case CutoffMode_Unique:
975 break;
976
977 // print cutoffNumber of digits or until we reach the buffer size
978 case CutoffMode_TotalLength:
979 {
980 tS32 desiredCutoffExponent = digitExponent - (tS32)cutoffNumber;
981 if (desiredCutoffExponent > cutoffExponent)
19
Taking false branch
982 cutoffExponent = desiredCutoffExponent;
983 }
984 break;
20
Execution continues on line 997
985
986 // print cutoffNumber digits past the decimal point or until we reach the buffer size
987 case CutoffMode_FractionLength:
988 {
989 tS32 desiredCutoffExponent = -(tS32)cutoffNumber;
990 if (desiredCutoffExponent > cutoffExponent)
991 cutoffExponent = desiredCutoffExponent;
992 }
993 break;
994 }
995
996 // Output the exponent of the first digit we will print
997 *pOutExponent = digitExponent-1;
998
999 // In preparation for calling BigInt_DivideWithRemainder_MaxQuotient9(),
1000 // we need to scale up our values such that the highest block of the denominator
1001 // is greater than or equal to 8. We also need to guarantee that the numerator
1002 // can never have a length greater than the denominator after each loop iteration.
1003 // This requires the highest block of the denominator to be less than or equal to
1004 // 429496729 which is the highest number that can be multiplied by 10 without
1005 // overflowing to a new block.
1006 RJ_ASSERT( scale.GetLength() > 0 );
1007 tU32 hiBlock = scale.GetBlock( scale.GetLength() - 1 );
1008 if (hiBlock < 8 || hiBlock > 429496729)
21
Assuming 'hiBlock' is >= 8
22
Assuming 'hiBlock' is > 429496729
23
Taking true branch
1009 {
1010 // Perform a bit shift on all values to get the highest block of the denominator into
1011 // the range [8,429496729]. We are more likely to make accurate quotient estimations
1012 // in BigInt_DivideWithRemainder_MaxQuotient9() with higher denominator values so
1013 // we shift the denominator to place the highest bit at index 27 of the highest block.
1014 // This is safe because (2^28 - 1) = 268435455 which is less than 429496729. This means
1015 // that all values with a highest bit at index 27 are within range.
1016 tU32 hiBlockLog2 = LogBase2(hiBlock);
1017 RJ_ASSERT(hiBlockLog2 < 3 || hiBlockLog2 > 27);
1018 tU32 shift = (32 + 27 - hiBlockLog2) % 32;
1019
1020 BigInt_ShiftLeft( &scale, shift );
1021 BigInt_ShiftLeft( &scaledValue, shift);
24
Calling 'BigInt_ShiftLeft'
29
Returning from 'BigInt_ShiftLeft'
1022 BigInt_ShiftLeft( &scaledMarginLow, shift);
1023 if (pScaledMarginHigh != &scaledMarginLow)
30
Taking false branch
1024 BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow );
1025 }
1026
1027 // These values are used to inspect why the print loop terminated so we can properly
1028 // round the final digit.
1029 tB low; // did the value get within marginLow distance from zero
1030 tB high; // did the value get within marginHigh distance from one
1031 tU32 outputDigit; // current digit being output
1032
1033 if (cutoffMode == CutoffMode_Unique)
31
Taking false branch
1034 {
1035 // For the unique cutoff mode, we will try to print until we have reached a level of
1036 // precision that uniquely distinguishes this value from its neighbors. If we run
1037 // out of space in the output buffer, we terminate early.
1038 for (;;)
1039 {
1040 digitExponent = digitExponent-1;
1041
1042 // divide out the scale to extract the digit
1043 outputDigit = BigInt_DivideWithRemainder_MaxQuotient9(&scaledValue, scale);
1044 RJ_ASSERT( outputDigit < 10 );
1045
1046 // update the high end of the value
1047 BigInt_Add( &scaledValueHigh, scaledValue, *pScaledMarginHigh );
1048
1049 // stop looping if we are far enough away from our neighboring values
1050 // or if we have reached the cutoff digit
1051 low = BigInt_Compare(scaledValue, scaledMarginLow) < 0;
1052 high = BigInt_Compare(scaledValueHigh, scale) > 0;
1053 if (low | high | (digitExponent == cutoffExponent))
1054 break;
1055
1056 // store the output digit
1057 *pCurDigit = (tC8)('0' + outputDigit);
1058 ++pCurDigit;
1059
1060 // multiply larger by the output base
1061 BigInt_Multiply10( &scaledValue );
1062 BigInt_Multiply10( &scaledMarginLow );
1063 if (pScaledMarginHigh != &scaledMarginLow)
1064 BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow );
1065 }
1066 }
1067 else
1068 {
1069 // For length based cutoff modes, we will try to print until we
1070 // have exhausted all precision (i.e. all remaining digits are zeros) or
1071 // until we reach the desired cutoff digit.
1072 low = false;
1073 high = false;
1074
1075 for (;;)
32
Loop condition is true. Entering loop body
1076 {
1077 digitExponent = digitExponent-1;
1078
1079 // divide out the scale to extract the digit
1080 outputDigit = BigInt_DivideWithRemainder_MaxQuotient9(&scaledValue, scale);
33
Calling 'BigInt_DivideWithRemainder_MaxQuotient9'
35
Returning from 'BigInt_DivideWithRemainder_MaxQuotient9'
1081 RJ_ASSERT( outputDigit < 10 );
1082
1083 if ( scaledValue.IsZero() | (digitExponent == cutoffExponent) )
36
Assuming 'digitExponent' is not equal to 'cutoffExponent'
37
Taking false branch
1084 break;
1085
1086 // store the output digit
1087 *pCurDigit = (tC8)('0' + outputDigit);
1088 ++pCurDigit;
1089
1090 // multiply larger by the output base
1091 BigInt_Multiply10(&scaledValue);
38
Calling 'BigInt_Multiply10'
1092 }
1093 }
1094
1095 // round off the final digit
1096 // default to rounding down if value got too close to 0
1097 tB roundDown = low;
1098
1099 // if it is legal to round up and down
1100 if (low == high)
1101 {
1102 // round to the closest digit by comparing value with 0.5. To do this we need to convert
1103 // the inequality to large integer values.
1104 // compare( value, 0.5 )
1105 // compare( scale * value, scale * 0.5 )
1106 // compare( 2 * scale * value, scale )
1107 BigInt_Multiply2(&scaledValue);
1108 tS32 compare = BigInt_Compare(scaledValue, scale);
1109 roundDown = compare < 0;
1110
1111 // if we are directly in the middle, round towards the even digit (i.e. IEEE rouding rules)
1112 if (compare == 0)
1113 roundDown = (outputDigit & 1) == 0;
1114 }
1115
1116 // print the rounded digit
1117 if (roundDown)
1118 {
1119 *pCurDigit = (tC8)('0' + outputDigit);
1120 ++pCurDigit;
1121 }
1122 else
1123 {
1124 // handle rounding up
1125 if (outputDigit == 9)
1126 {
1127 // find the first non-nine prior digit
1128 for (;;)
1129 {
1130 // if we are at the first digit
1131 if (pCurDigit == pOutBuffer)
1132 {
1133 // output 1 at the next highest exponent
1134 *pCurDigit = '1';
1135 ++pCurDigit;
1136 *pOutExponent += 1;
1137 break;
1138 }
1139
1140 --pCurDigit;
1141 if (*pCurDigit != '9')
1142 {
1143 // increment the digit
1144 *pCurDigit += 1;
1145 ++pCurDigit;
1146 break;
1147 }
1148 }
1149 }
1150 else
1151 {
1152 // values in the range [0,8] can perform a simple round up
1153 *pCurDigit = (tC8)('0' + outputDigit + 1);
1154 ++pCurDigit;
1155 }
1156 }
1157
1158 // return the number of digits output
1159 RJ_ASSERT(pCurDigit - pOutBuffer <= (tPtrDiff)bufferSize);
1160 return pCurDigit - pOutBuffer;
1161}
diff --git a/scan-build/report-3a56cc.html b/scan-build/report-3a56cc.html deleted file mode 100644 index d6e84256..00000000 --- a/scan-build/report-3a56cc.html +++ /dev/null @@ -1,447 +0,0 @@ - - - -lib/real/pow.c - - - - - - - - - - - - - - - - - - - - - - - - - -

Bug Summary

- - - - -
File:real/pow.c
Location:line 148, column 5
Description:Value stored to 'i1' is never read
- -

Annotated Source Code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/* @(#)e_pow.c 1.5 04/04/22 SMI */
2
3/*
4 * Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * The origin source code can be obtained from:
28 * http://www.netlib.org/fdlibm/e_pow.c
29 *
30 */
31
32/*
33 * ====================================================
34 * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
35 *
36 * Permission to use, copy, modify, and distribute this
37 * software is freely granted, provided that this notice
38 * is preserved.
39 * ====================================================
40 */
41
42#include "prim.h"
43#include "math.h"
44
45#ifdef __clang__1
46# pragma clang diagnostic ignored "-Wunused-variable"
47# pragma clang diagnostic ignored "-Wstrict-aliasing"
48#elif defined(__GNUC__4) && __GNUC__4 > 2
49# pragma GCC diagnostic ignored "-Wunused-but-set-variable"
50# pragma GCC diagnostic ignored "-Wstrict-aliasing"
51#endif
52
53static const double
54bp[] = {1.0, 1.5,},
55dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */
56dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */
57zero = 0.0,
58one = 1.0,
59two = 2.0,
60two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */
61huge = 1.0e300,
62tiny = 1.0e-300,
63 /* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
64L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */
65L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */
66L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */
67L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */
68L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */
69L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */
70P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
71P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
72P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
73P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
74P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */
75lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
76lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */
77lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */
78ovt = 8.0085662595372944372e-0017, /* -(1024-log2(ovfl+.5ulp)) */
79cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */
80cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */
81cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/
82ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */
83ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/
84ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/
85
86/**
87 * @brief Expontation function.
88 * @version 1.3
89 * @date 95/01/18
90 * @details
91 * <pre>
92 * Method: Let x = 2 * (1+f)
93 * 1. Compute and return log2(x) in two pieces:
94 * log2(x) = w1 + w2,
95 * where w1 has 53-24 = 29 bit trailing zeros.
96 * 2. Perform y*log2(x) = n+y' by simulating muti-precision
97 * arithmetic, where |y'|<=0.5.
98 * 3. Return x**y = 2**n*exp(y'*log2)
99 *
100 * Special cases:
101 * 1. (anything) ** 0 is 1
102 * 2. (anything) ** 1 is itself
103 * 3. (anything) ** NAN is NAN
104 * 4. NAN ** (anything except 0) is NAN
105 * 5. +-(|x| > 1) ** +INF is +INF
106 * 6. +-(|x| > 1) ** -INF is +0
107 * 7. +-(|x| < 1) ** +INF is +0
108 * 8. +-(|x| < 1) ** -INF is +INF
109 * 9. +-1 ** +-INF is NAN
110 * 10. +0 ** (+anything except 0, NAN) is +0
111 * 11. -0 ** (+anything except 0, NAN, odd integer) is +0
112 * 12. +0 ** (-anything except 0, NAN) is +INF
113 * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF
114 * 14. -0 ** (odd integer) = -( +0 ** (odd integer) )
115 * 15. +INF ** (+anything except 0,NAN) is +INF
116 * 16. +INF ** (-anything except 0,NAN) is +0
117 * 17. -INF ** (anything) = -0 ** (-anything)
118 * 18. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
119 * 19. (-anything except 0 and inf) ** (non-integer) is NAN
120 *
121 * Accuracy:
122 * pow(x,y) returns x**y nearly rounded. In particular
123 * pow(integer,integer)
124 * always returns the correct integer provided it is
125 * representable.
126 *
127 * Constants :
128 * The hexadecimal values are the intended ones for the following
129 * constants. The decimal values may be used, provided that the
130 * compiler will convert from decimal to binary accurately enough
131 * to produce the hexadecimal values shown.
132 * </pre>
133 * @copyright Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
134 * @license Developed at SunSoft, a Sun Microsystems, Inc. business. Permission
135 * to use, copy, modify, and distribute this software is freely granted,
136 * provided that this notice is preserved.
137 */
138
139double pow(double x, double y)
140{
141 double z,ax,z_h,z_l,p_h,p_l;
142 double y1,t1,t2,r,s,t,u,v,w;
143 sword i0,i1,i,j,k,yisint,n;
144 sword hx,hy,ix,iy;
145 uword lx,ly;
146
147 i0 = ((*(int*)&one)>>29)^1;
148 i1=1-i0;
Value stored to 'i1' is never read
149 EXTRACT_WORDS(hx,lx,x)do { ieee_double_shape_type ew_u; ew_u.value = (x); (hx) = ew_u
.parts.msw; (lx) = ew_u.parts.lsw; } while (0)
;
150 EXTRACT_WORDS(hy,ly,y)do { ieee_double_shape_type ew_u; ew_u.value = (y); (hy) = ew_u
.parts.msw; (ly) = ew_u.parts.lsw; } while (0)
;
151 ix = hx&0x7fffffff;
152 iy = hy&0x7fffffff;
153
154 /* y==zero: x**0 = 1 */
155 if((iy|ly)==0) return one;
156
157 /* +-NaN return x+y */
158 if(ix > 0x7ff00000 || ((ix==0x7ff00000)&&(lx!=0)) ||
159 iy > 0x7ff00000 || ((iy==0x7ff00000)&&(ly!=0)))
160 return x+y;
161
162 /* determine if y is an odd int when x < 0
163 * yisint = 0 ... y is not an integer
164 * yisint = 1 ... y is an odd int
165 * yisint = 2 ... y is an even int
166 */
167 yisint = 0;
168 if(hx<0) {
169 if(iy>=0x43400000) yisint = 2; /* even integer y */
170 else if(iy>=0x3ff00000) {
171 k = (iy>>20)-0x3ff; /* exponent */
172 if(k>20) {
173 j = ly>>(52-k);
174 if((uword)(j<<(52-k))==ly) yisint = 2-(j&1);
175 } else if(ly==0) {
176 j = iy>>(20-k);
177 if((j<<(20-k))==iy) yisint = 2-(j&1);
178 }
179 }
180 }
181
182 /* special value of y */
183 if(ly==0) {
184 if (iy==0x7ff00000) { /* y is +-inf */
185 if(((ix-0x3ff00000)|lx)==0)
186 return y - y; /* inf**+-1 is NaN */
187 else if (ix >= 0x3ff00000)/* (|x|>1)**+-inf = inf,0 */
188 return (hy>=0)? y: zero;
189 else /* (|x|<1)**-,+inf = inf,0 */
190 return (hy<0)?-y: zero;
191 }
192 if(iy==0x3ff00000) { /* y is +-1 */
193 if(hy<0) return one/x;
194 else return x;
195 }
196 if(hy==0x40000000) return x*x; /* y is 2 */
197 if(hy==0x3fe00000) { /* y is 0.5 */
198 if(hx>=0) /* x >= +0 */
199 return sqrt(x);
200 }
201 }
202
203 ax = fabs(x);
204 /* special value of x */
205 if(lx==0) {
206 if(ix==0x7ff00000||ix==0||ix==0x3ff00000) {
207 z = ax; /*x is +-0,+-inf,+-1*/
208 if(hy<0) z = one/z; /* z = (1/|x|) */
209 if(hx<0) {
210 if(((ix-0x3ff00000)|yisint)==0) {
211 z = (z-z)/(z-z); /* (-1)**non-int is NaN */
212 } else if(yisint==1)
213 z = -z; /* (x<0)**odd = -(|x|**odd) */
214 }
215 return z;
216 }
217 }
218
219 n = (hx>>31)+1;
220
221 /* (x<0)**(non-int) is NaN */
222 if((n|yisint)==0) return (x-x)/(x-x);
223
224 s = one; /* s (sign of result -ve**odd) = -1 else = 1 */
225 if((n|(yisint-1))==0) s = -one;/* (-ve)**(odd int) */
226
227 /* |y| is huge */
228 if(iy>0x41e00000) { /* if |y| > 2**31 */
229 if(iy>0x43f00000) { /* if |y| > 2**64, must o/uflow */
230 if(ix<=0x3fefffff) return (hy<0)? huge*huge:tiny*tiny;
231 if(ix>=0x3ff00000) return (hy>0)? huge*huge:tiny*tiny;
232 }
233 /* over/underflow if x is not close to one */
234 if(ix<0x3fefffff) return (hy<0)? s*huge*huge:s*tiny*tiny;
235 if(ix>0x3ff00000) return (hy>0)? s*huge*huge:s*tiny*tiny;
236 /* now |1-x| is tiny <= 2**-20, suffice to compute
237 log(x) by x-x^2/2+x^3/3-x^4/4 */
238 t = ax-one; /* t has 20 trailing zeros */
239 w = (t*t)*(0.5-t*(0.3333333333333333333333-t*0.25));
240 u = ivln2_h*t; /* ivln2_h has 21 sig. bits */
241 v = t*ivln2_l-w*ivln2;
242 t1 = u+v;
243 SET_LOW_WORD(t1,0)do { ieee_double_shape_type sl_u; sl_u.value = (t1); sl_u.parts
.lsw = (0); (t1) = sl_u.value; } while (0)
;
244 t2 = v-(t1-u);
245 } else {
246 double ss,s2,s_h,s_l,t_h,t_l;
247 n = 0;
248 /* take care subnormal number */
249 if(ix<0x00100000)
250 {
251 ax *= two53;
252 n -= 53;
253 GET_HIGH_WORD(ix,ax)do { ieee_double_shape_type gh_u; gh_u.value = (ax); (ix) = gh_u
.parts.msw; } while (0)
;
254 }
255 n += ((ix)>>20)-0x3ff;
256 j = ix&0x000fffff;
257 /* determine interval */
258 ix = j|0x3ff00000; /* normalize ix */
259 if(j<=0x3988E) k=0; /* |x|<sqrt(3/2) */
260 else if(j<0xBB67A) k=1; /* |x|<sqrt(3) */
261 else {
262 k=0;
263 n+=1;
264 ix -= 0x00100000;
265 }
266 SET_HIGH_WORD(ax,ix)do { ieee_double_shape_type sh_u; sh_u.value = (ax); sh_u.parts
.msw = (ix); (ax) = sh_u.value; } while (0)
;
267
268 /* compute ss = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
269 u = ax-bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
270 v = one/(ax+bp[k]);
271 ss = u*v;
272 s_h = ss;
273 SET_LOW_WORD(s_h,0)do { ieee_double_shape_type sl_u; sl_u.value = (s_h); sl_u.parts
.lsw = (0); (s_h) = sl_u.value; } while (0)
;
274 /* t_h=ax+bp[k] High */
275 t_h = zero;
276 SET_HIGH_WORD(t_h,((ix>>1)|0x20000000)+0x00080000+(k<<18))do { ieee_double_shape_type sh_u; sh_u.value = (t_h); sh_u.parts
.msw = (((ix>>1)|0x20000000)+0x00080000+(k<<18));
(t_h) = sh_u.value; } while (0)
;
277 t_l = ax - (t_h-bp[k]);
278 s_l = v*((u-s_h*t_h)-s_h*t_l);
279 /* compute log(ax) */
280 s2 = ss*ss;
281 r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
282 r += s_l*(s_h+ss);
283 s2 = s_h*s_h;
284 t_h = 3.0+s2+r;
285 SET_LOW_WORD(t_h,0)do { ieee_double_shape_type sl_u; sl_u.value = (t_h); sl_u.parts
.lsw = (0); (t_h) = sl_u.value; } while (0)
;
286 t_l = r-((t_h-3.0)-s2);
287 /* u+v = ss*(1+...) */
288 u = s_h*t_h;
289 v = s_l*t_h+t_l*ss;
290 /* 2/(3log2)*(ss+...) */
291 p_h = u+v;
292 SET_LOW_WORD(p_h,0)do { ieee_double_shape_type sl_u; sl_u.value = (p_h); sl_u.parts
.lsw = (0); (p_h) = sl_u.value; } while (0)
;
293 p_l = v-(p_h-u);
294 z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */
295 z_l = cp_l*p_h+p_l*cp+dp_l[k];
296 /* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */
297 t = (double)n;
298 t1 = (((z_h+z_l)+dp_h[k])+t);
299 SET_LOW_WORD(t1,0)do { ieee_double_shape_type sl_u; sl_u.value = (t1); sl_u.parts
.lsw = (0); (t1) = sl_u.value; } while (0)
;
300 t2 = z_l-(((t1-t)-dp_h[k])-z_h);
301 }
302
303 /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
304 y1 = y;
305 SET_LOW_WORD(y1,0)do { ieee_double_shape_type sl_u; sl_u.value = (y1); sl_u.parts
.lsw = (0); (y1) = sl_u.value; } while (0)
;
306 p_l = (y-y1)*t1+y*t2;
307 p_h = y1*t1;
308 z = p_l+p_h;
309 EXTRACT_WORDS(j,i,z)do { ieee_double_shape_type ew_u; ew_u.value = (z); (j) = ew_u
.parts.msw; (i) = ew_u.parts.lsw; } while (0)
;
310 if (j>=0x40900000) { /* z >= 1024 */
311 if(((j-0x40900000)|i)!=0) /* if z > 1024 */
312 return s*huge*huge; /* overflow */
313 else {
314 if(p_l+ovt>z-p_h) return s*huge*huge; /* overflow */
315 }
316 } else if((j&0x7fffffff)>=0x4090cc00 ) { /* z <= -1075 */
317 if(((j-0xc090cc00)|i)!=0) /* z < -1075 */
318 return s*tiny*tiny; /* underflow */
319 else {
320 if(p_l<=z-p_h) return s*tiny*tiny; /* underflow */
321 }
322 }
323 /*
324 * compute 2**(p_h+p_l)
325 */
326 i = j&0x7fffffff;
327 k = (i>>20)-0x3ff;
328 n = 0;
329 if(i>0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */
330 n = j+(0x00100000>>(k+1));
331 k = ((n&0x7fffffff)>>20)-0x3ff; /* new k for n */
332 t = zero;
333 SET_HIGH_WORD(t,(n&~(0x000fffff>>k)))do { ieee_double_shape_type sh_u; sh_u.value = (t); sh_u.parts
.msw = ((n&~(0x000fffff>>k))); (t) = sh_u.value; } while
(0)
;
334 n = ((n&0x000fffff)|0x00100000)>>(20-k);
335 if(j<0) n = -n;
336 p_h -= t;
337 }
338 t = p_l+p_h;
339 SET_LOW_WORD(t,0)do { ieee_double_shape_type sl_u; sl_u.value = (t); sl_u.parts
.lsw = (0); (t) = sl_u.value; } while (0)
;
340 u = t*lg2_h;
341 v = (p_l-(t-p_h))*lg2+t*lg2_l;
342 z = u+v;
343 w = v-(z-u);
344 t = z*z;
345 t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
346 r = (z*t1)/(t1-two)-(w+z*w);
347 z = one-(r-z);
348 GET_HIGH_WORD(j,z)do { ieee_double_shape_type gh_u; gh_u.value = (z); (j) = gh_u
.parts.msw; } while (0)
;
349 j += (n<<20);
350 if((j>>20)<=0) z = scalbn(z,n); /* subnormal output */
351 else
352 {
353 uword hz;
354 GET_HIGH_WORD(hz,z)do { ieee_double_shape_type gh_u; gh_u.value = (z); (hz) = gh_u
.parts.msw; } while (0)
;
355 SET_HIGH_WORD(z,hz + (n<<20))do { ieee_double_shape_type sh_u; sh_u.value = (z); sh_u.parts
.msw = (hz + (n<<20)); (z) = sh_u.value; } while (0)
;
356 }
357 return s*z;
358}
diff --git a/scan-build/report-40d42f.html b/scan-build/report-40d42f.html deleted file mode 100644 index af497936..00000000 --- a/scan-build/report-40d42f.html +++ /dev/null @@ -1,781 +0,0 @@ - - - -lib/dconv/dprint.cpp - - - - - - - - - - - - - - - - - - - - - - - - - -

Bug Summary

- - - - -
File:dconv/dprint.cpp
Location:line 385, column 9
Description:Value stored to 'bufferSize' is never read
- -

Annotated Source Code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/******************************************************************************
2 Copyright (c) 2014 Ryan Juckett
3 http://www.ryanjuckett.com/
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20
21 3. This notice may not be removed or altered from any source
22 distribution.
23*******************************************************************************
24 Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
25 All rights reserved.
26
27 Redistribution and use in source and binary forms, with or without
28 modification, are permitted provided that the following conditions
29 are met:
30 1. Redistributions of source code must retain the above copyright
31 notice, this list of conditions and the following disclaimer.
32
33 2. Redistributions in binary form must reproduce the above copyright
34 notice, this list of conditions and the following disclaimer in the
35 documentation and/or other materials provided with the distribution.
36
37 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
38 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
40 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
41 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
46 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47
48 The origin source code can be obtained from:
49 http://www.ryanjuckett.com/
50
51******************************************************************************/
52
53#include "clib.h"
54#include "dmath.h"
55#include "dprint.h"
56#include "dragon4.h"
57#include <dstandard.h>
58
59#define memcpyMemCopy MemCopy
60#define memmoveMemCopy MemCopy
61
62//******************************************************************************
63// Helper union to decompose a 32-bit IEEE float.
64// sign: 1 bit
65// exponent: 8 bits
66// mantissa: 23 bits
67//******************************************************************************
68union tFloatUnion32
69{
70 tB IsNegative() const {
71 return (m_integer >> 31) != 0;
72 }
73 tU32 GetExponent() const {
74 return (m_integer >> 23) & 0xFF;
75 }
76 tU32 GetMantissa() const {
77 return m_integer & 0x7FFFFF;
78 }
79
80 tF32 m_floatingPoint;
81 tU32 m_integer;
82};
83
84//******************************************************************************
85// Helper union to decompose a 64-bit IEEE float.
86// sign: 1 bit
87// exponent: 11 bits
88// mantissa: 52 bits
89//******************************************************************************
90union tFloatUnion64
91{
92 tB IsNegative() const {
93 return (m_integer >> 63) != 0;
94 }
95 tU32 GetExponent() const {
96 return (m_integer >> 52) & 0x7FF;
97 }
98 tU64 GetMantissa() const {
99 return m_integer & 0xFFFFFFFFFFFFFull;
100 }
101
102 tF64 m_floatingPoint;
103 tU64 m_integer;
104};
105
106//******************************************************************************
107// Outputs the positive number with positional notation: ddddd.dddd
108// The output is always NUL terminated and the output length (not including the
109// NUL) is returned.
110//******************************************************************************
111tU32 FormatPositional
112(
113 tC8 * pOutBuffer, // buffer to output into
114 tU32 bufferSize, // maximum characters that can be printed to pOutBuffer
115 tU64 mantissa, // value significand
116 tS32 exponent, // value exponent in base 2
117 tU32 mantissaHighBitIdx, // index of the highest set mantissa bit
118 tB hasUnequalMargins, // is the high margin twice as large as the low margin
119 tS32 precision, // Negative prints as many digits as are needed for a unique
120 tC8 decimalPoint // Character before the decimals
121 // number. Positive specifies the maximum number of
122 // significant digits to print past the decimal point.
123)
124{
125 RJ_ASSERT(bufferSize > 0);
126
127 tS32 printExponent;
128 tU32 numPrintDigits;
129
130 tU32 maxPrintLen = bufferSize - 1;
131
132 if (precision < 0)
133 {
134 numPrintDigits = Dragon4( mantissa,
135 exponent,
136 mantissaHighBitIdx,
137 hasUnequalMargins,
138 CutoffMode_Unique,
139 0,
140 pOutBuffer,
141 maxPrintLen,
142 &printExponent );
143 }
144 else
145 {
146 numPrintDigits = Dragon4( mantissa,
147 exponent,
148 mantissaHighBitIdx,
149 hasUnequalMargins,
150 CutoffMode_FractionLength,
151 precision,
152 pOutBuffer,
153 maxPrintLen,
154 &printExponent );
155 }
156
157 RJ_ASSERT( numPrintDigits > 0 );
158 RJ_ASSERT( numPrintDigits <= bufferSize );
159
160 // track the number of digits past the decimal point that have been printed
161 tU32 numFractionDigits = 0;
162
163 // if output has a whole number
164 if (printExponent >= 0)
165 {
166 // leave the whole number at the start of the buffer
167 tU32 numWholeDigits = printExponent+1;
168 if (numPrintDigits < numWholeDigits)
169 {
170 // don't overflow the buffer
171 if (numWholeDigits > maxPrintLen)
172 numWholeDigits = maxPrintLen;
173
174 // add trailing zeros up to the decimal point
175 for ( ; numPrintDigits < numWholeDigits; ++numPrintDigits )
176 pOutBuffer[numPrintDigits] = '0';
177 }
178 // insert the decimal point prior to the fraction
179 else if (numPrintDigits > (tU32)numWholeDigits)
180 {
181 numFractionDigits = numPrintDigits - numWholeDigits;
182 tU32 maxFractionDigits = maxPrintLen - numWholeDigits - 1;
183 if (numFractionDigits > maxFractionDigits)
184 numFractionDigits = maxFractionDigits;
185
186 memmoveMemCopy(pOutBuffer + numWholeDigits + 1, pOutBuffer + numWholeDigits, numFractionDigits);
187 pOutBuffer[numWholeDigits] = decimalPoint;
188 numPrintDigits = numWholeDigits + 1 + numFractionDigits;
189 }
190 }
191 else
192 {
193 // shift out the fraction to make room for the leading zeros
194 if (maxPrintLen > 2)
195 {
196 tU32 numFractionZeros = (tU32)-printExponent - 1;
197 tU32 maxFractionZeros = maxPrintLen - 2;
198 if (numFractionZeros > maxFractionZeros)
199 numFractionZeros = maxFractionZeros;
200
201 tU32 digitsStartIdx = 2 + numFractionZeros;
202
203 // shift the significant digits right such that there is room for leading zeros
204 numFractionDigits = numPrintDigits;
205 tU32 maxFractionDigits = maxPrintLen - digitsStartIdx;
206 if (numFractionDigits > maxFractionDigits)
207 numFractionDigits = maxFractionDigits;
208
209 memmoveMemCopy(pOutBuffer + digitsStartIdx, pOutBuffer, numFractionDigits);
210
211 // insert the leading zeros
212 for (tU32 i = 2; i < digitsStartIdx; ++i)
213 pOutBuffer[i] = '0';
214
215 // update the counts
216 numFractionDigits += numFractionZeros;
217 numPrintDigits = numFractionDigits;
218 }
219
220 // add the decimal point
221 if (maxPrintLen > 1)
222 {
223 pOutBuffer[1] = decimalPoint;
224 numPrintDigits += 1;
225 }
226
227 // add the initial zero
228 if (maxPrintLen > 0)
229 {
230 pOutBuffer[0] = '0';
231 numPrintDigits += 1;
232 }
233 }
234
235 // add trailing zeros up to precision length
236 if (precision > (tS32)numFractionDigits && numPrintDigits < maxPrintLen)
237 {
238 // add a decimal point if this is the first fractional digit we are printing
239 if (numFractionDigits == 0)
240 {
241 pOutBuffer[numPrintDigits++] = decimalPoint;
242 }
243
244 // compute the number of trailing zeros needed
245 tU32 totalDigits = numPrintDigits + (precision - numFractionDigits);
246 if (totalDigits > maxPrintLen)
247 totalDigits = maxPrintLen;
248
249 for ( ; numPrintDigits < totalDigits; ++numPrintDigits )
250 pOutBuffer[numPrintDigits] = '0';
251 }
252
253 // terminate the buffer
254 RJ_ASSERT( numPrintDigits <= maxPrintLen );
255 pOutBuffer[numPrintDigits] = '\0';
256
257 return numPrintDigits;
258}
259
260//******************************************************************************
261// Outputs the positive number with scientific notation: d.dddde[sign]ddd
262// The output is always NUL terminated and the output length (not including the
263// NUL) is returned.
264//******************************************************************************
265tU32 FormatScientific
266(
267 tC8 * pOutBuffer, // buffer to output into
268 tU32 bufferSize, // maximum characters that can be printed to pOutBuffer
269 tU64 mantissa, // value significand
270 tS32 exponent, // value exponent in base 2
271 tU32 mantissaHighBitIdx, // index of the highest set mantissa bit
272 tB hasUnequalMargins, // is the high margin twice as large as the low margin
273 tS32 precision, // Negative prints as many digits as are needed for a unique
274 tC8 decimalPoint // Character before the decimals
275 // number. Positive specifies the maximum number of
276 // significant digits to print past the decimal point.
277)
278{
279 RJ_ASSERT(bufferSize > 0);
280
281 tS32 printExponent;
282 tU32 numPrintDigits;
283
284 if (precision < 0)
285 {
286 numPrintDigits = Dragon4( mantissa,
287 exponent,
288 mantissaHighBitIdx,
289 hasUnequalMargins,
290 CutoffMode_Unique,
291 0,
292 pOutBuffer,
293 bufferSize,
294 &printExponent );
295 }
296 else
297 {
298 numPrintDigits = Dragon4( mantissa,
299 exponent,
300 mantissaHighBitIdx,
301 hasUnequalMargins,
302 CutoffMode_TotalLength,
303 precision + 1,
304 pOutBuffer,
305 bufferSize,
306 &printExponent );
307 }
308
309 RJ_ASSERT( numPrintDigits > 0 );
310 RJ_ASSERT( numPrintDigits <= bufferSize );
311
312 tC8 * pCurOut = pOutBuffer;
313
314 // keep the whole number as the first digit
315 if (bufferSize > 1)
316 {
317 pCurOut += 1;
318 bufferSize -= 1;
319 }
320
321 // insert the decimal point prior to the fractional number
322 tU32 numFractionDigits = numPrintDigits-1;
323 if (numFractionDigits > 0 && bufferSize > 1)
324 {
325 tU32 maxFractionDigits = bufferSize-2;
326 if (numFractionDigits > maxFractionDigits)
327 numFractionDigits = maxFractionDigits;
328
329 memmoveMemCopy(pCurOut + 1, pCurOut, numFractionDigits);
330 pCurOut[0] = decimalPoint;
331 pCurOut += (1 + numFractionDigits);
332 bufferSize -= (1 + numFractionDigits);
333 }
334
335 // add trailing zeros up to precision length
336 if (precision > (tS32)numFractionDigits && bufferSize > 1)
337 {
338 // add a decimal point if this is the first fractional digit we are printing
339 if (numFractionDigits == 0)
340 {
341 *pCurOut = decimalPoint;
342 ++pCurOut;
343 --bufferSize;
344 }
345
346 // compute the number of trailing zeros needed
347 tU32 numZeros = (precision - numFractionDigits);
348 if (numZeros > bufferSize-1)
349 numZeros = bufferSize-1;
350
351 for (tC8 * pEnd = pCurOut + numZeros; pCurOut < pEnd; ++pCurOut )
352 *pCurOut = '0';
353 }
354
355 // print the exponent into a local buffer and copy into output buffer
356 if (bufferSize > 1)
357 {
358 tC8 exponentBuffer[5];
359 exponentBuffer[0] = 'e';
360 if (printExponent >= 0)
361 {
362 exponentBuffer[1] = '+';
363 }
364 else
365 {
366 exponentBuffer[1] = '-';
367 printExponent = -printExponent;
368 }
369
370 RJ_ASSERT(printExponent < 1000);
371 tU32 hundredsPlace = printExponent / 100;
372 tU32 tensPlace = (printExponent - hundredsPlace*100) / 10;
373 tU32 onesPlace = (printExponent - hundredsPlace*100 - tensPlace*10);
374
375 exponentBuffer[2] = (tC8)('0' + hundredsPlace);
376 exponentBuffer[3] = (tC8)('0' + tensPlace);
377 exponentBuffer[4] = (tC8)('0' + onesPlace);
378
379 // copy the exponent buffer into the output
380 tU32 maxExponentSize = bufferSize-1;
381 tU32 exponentSize = (5 < maxExponentSize) ? 5 : maxExponentSize;
382 memcpyMemCopy( pCurOut, exponentBuffer, exponentSize );
383
384 pCurOut += exponentSize;
385 bufferSize -= exponentSize;
Value stored to 'bufferSize' is never read
386 }
387
388 RJ_ASSERT( bufferSize > 0 );
389 pCurOut[0] = '\0';
390
391 return pCurOut - pOutBuffer;
392}
393
394//******************************************************************************
395// Print a hexadecimal value with a given width.
396// The output string is always NUL terminated and the string length (not
397// including the NUL) is returned.
398//******************************************************************************
399static tU32 PrintHex(tC8 * pOutBuffer, tU32 bufferSize, tU64 value, tU32 width)
400{
401 const tC8 digits[] = "0123456789abcdef";
402
403 RJ_ASSERT(bufferSize > 0);
404
405 tU32 maxPrintLen = bufferSize-1;
406 if (width > maxPrintLen)
407 width = maxPrintLen;
408
409 tC8 * pCurOut = pOutBuffer;
410 while (width > 0)
411 {
412 --width;
413
414 tU8 digit = (tU8)((value >> 4ull*(tU64)width) & 0xF);
415 *pCurOut = digits[digit];
416
417 ++pCurOut;
418 }
419
420 *pCurOut = '\0';
421 return pCurOut - pOutBuffer;
422}
423
424//******************************************************************************
425// Print special case values for infinities and NaNs.
426// The output string is always NUL terminated and the string length (not
427// including the NUL) is returned.
428//******************************************************************************
429static tU32 PrintInfNan(tC8 * pOutBuffer, tU32 bufferSize, tU64 mantissa, tU32 mantissaHexWidth)
430{
431 RJ_ASSERT(bufferSize > 0);
432
433 tU32 maxPrintLen = bufferSize-1;
434
435 // Check for infinity
436 if (mantissa == 0)
437 {
438 // copy and make sure the buffer is terminated
439 tU32 printLen = (3 < maxPrintLen) ? 3 : maxPrintLen;
440 ::memcpyMemCopy( pOutBuffer, "Inf", printLen );
441 pOutBuffer[printLen] = '\0';
442 return printLen;
443 }
444 else
445 {
446 // copy and make sure the buffer is terminated
447 tU32 printLen = (3 < maxPrintLen) ? 3 : maxPrintLen;
448 ::memcpyMemCopy( pOutBuffer, "NaN", printLen );
449 pOutBuffer[printLen] = '\0';
450
451 // append HEX value
452 if (maxPrintLen > 3)
453 printLen += PrintHex(pOutBuffer+3, bufferSize-3, mantissa, mantissaHexWidth);
454
455 return printLen;
456 }
457}
458
459//******************************************************************************
460// Print a 32-bit floating-point number as a decimal string.
461// The output string is always NUL terminated and the string length (not
462// including the NUL) is returned.
463//******************************************************************************
464tU32 PrintFloat32
465(
466 tC8 * pOutBuffer, // buffer to output into
467 tU32 bufferSize, // size of pOutBuffer
468 tF32 value, // value to print
469 tPrintFloatFormat format, // format to print with
470 tS32 precision, // If negative, the minimum number of digits to represent a
471 tC8 decimalPoint // Character before the decimals
472 // unique 32-bit floating point value is output. Otherwise,
473 // this is the number of digits to print past the decimal point.
474)
475{
476 if (bufferSize == 0)
477 return 0;
478
479 if (bufferSize == 1)
480 {
481 pOutBuffer[0] = '\0';
482 return 1;
483 }
484
485 // deconstruct the floating point value
486 tFloatUnion32 floatUnion;
487 floatUnion.m_floatingPoint = value;
488 tU32 floatExponent = floatUnion.GetExponent();
489 tU32 floatMantissa = floatUnion.GetMantissa();
490
491 // output the sign
492 if (floatUnion.IsNegative())
493 {
494 pOutBuffer[0] = '-';
495 ++pOutBuffer;
496 --bufferSize;
497 RJ_ASSERT(bufferSize > 0);
498 }
499
500 // if this is a special value
501 if (floatExponent == 0xFF)
502 {
503 return PrintInfNan(pOutBuffer, bufferSize, floatMantissa, 6);
504 }
505 // else this is a number
506 else
507 {
508 // factor the value into its parts
509 tU32 mantissa;
510 tS32 exponent;
511 tU32 mantissaHighBitIdx;
512 tB hasUnequalMargins;
513 if (floatExponent != 0)
514 {
515 // normalized
516 // The floating point equation is:
517 // value = (1 + mantissa/2^23) * 2 ^ (exponent-127)
518 // We convert the integer equation by factoring a 2^23 out of the exponent
519 // value = (1 + mantissa/2^23) * 2^23 * 2 ^ (exponent-127-23)
520 // value = (2^23 + mantissa) * 2 ^ (exponent-127-23)
521 // Because of the implied 1 in front of the mantissa we have 24 bits of precision.
522 // m = (2^23 + mantissa)
523 // e = (exponent-127-23)
524 mantissa = (1UL << 23) | floatMantissa;
525 exponent = floatExponent - 127 - 23;
526 mantissaHighBitIdx = 23;
527 hasUnequalMargins = (floatExponent != 1) && (floatMantissa == 0);
528 }
529 else
530 {
531 // denormalized
532 // The floating point equation is:
533 // value = (mantissa/2^23) * 2 ^ (1-127)
534 // We convert the integer equation by factoring a 2^23 out of the exponent
535 // value = (mantissa/2^23) * 2^23 * 2 ^ (1-127-23)
536 // value = mantissa * 2 ^ (1-127-23)
537 // We have up to 23 bits of precision.
538 // m = (mantissa)
539 // e = (1-127-23)
540 mantissa = floatMantissa;
541 exponent = 1 - 127 - 23;
542 mantissaHighBitIdx = LogBase2(mantissa);
543 hasUnequalMargins = false;
544 }
545
546 // format the value
547 switch (format)
548 {
549 case PrintFloatFormat_Positional:
550 return FormatPositional( pOutBuffer,
551 bufferSize,
552 mantissa,
553 exponent,
554 mantissaHighBitIdx,
555 hasUnequalMargins,
556 precision,
557 decimalPoint );
558
559 case PrintFloatFormat_Scientific:
560 return FormatScientific( pOutBuffer,
561 bufferSize,
562 mantissa,
563 exponent,
564 mantissaHighBitIdx,
565 hasUnequalMargins,
566 precision,
567 decimalPoint );
568
569 default:
570 pOutBuffer[0] = '\0';
571 return 0;
572 }
573 }
574}
575
576//******************************************************************************
577// Print a 64-bit floating-point number as a decimal string.
578// The output string is always NUL terminated and the string length (not
579// including the NUL) is returned.
580//******************************************************************************
581tU32 PrintFloat64
582(
583 tC8 * pOutBuffer, // buffer to output into
584 tU32 bufferSize, // size of pOutBuffer
585 tF64 value, // value to print
586 tPrintFloatFormat format, // format to print with
587 tS32 precision, // If negative, the minimum number of digits to represent a
588 tC8 decimalPoint // Character before the decimals
589 // unique 64-bit floating point value is output. Otherwise,
590 // this is the number of digits to print past the decimal point.
591)
592{
593 if (bufferSize == 0)
594 return 0;
595
596 if (bufferSize == 1)
597 {
598 pOutBuffer[0] = '\0';
599 return 1;
600 }
601
602 // deconstruct the floating point value
603 tFloatUnion64 floatUnion;
604 floatUnion.m_floatingPoint = value;
605 tU32 floatExponent = floatUnion.GetExponent();
606 tU64 floatMantissa = floatUnion.GetMantissa();
607
608 // output the sign
609 if (floatUnion.IsNegative())
610 {
611 pOutBuffer[0] = '-';
612 ++pOutBuffer;
613 --bufferSize;
614 RJ_ASSERT(bufferSize > 0);
615 }
616
617 // if this is a special value
618 if (floatExponent == 0x7FF)
619 {
620 return PrintInfNan(pOutBuffer, bufferSize, floatMantissa, 13);
621 }
622 // else this is a number
623 else
624 {
625 // factor the value into its parts
626 tU64 mantissa;
627 tS32 exponent;
628 tU32 mantissaHighBitIdx;
629 tB hasUnequalMargins;
630
631 if (floatExponent != 0)
632 {
633 // normal
634 // The floating point equation is:
635 // value = (1 + mantissa/2^52) * 2 ^ (exponent-1023)
636 // We convert the integer equation by factoring a 2^52 out of the exponent
637 // value = (1 + mantissa/2^52) * 2^52 * 2 ^ (exponent-1023-52)
638 // value = (2^52 + mantissa) * 2 ^ (exponent-1023-52)
639 // Because of the implied 1 in front of the mantissa we have 53 bits of precision.
640 // m = (2^52 + mantissa)
641 // e = (exponent-1023+1-53)
642 mantissa = (1ull << 52) | floatMantissa;
643 exponent = floatExponent - 1023 - 52;
644 mantissaHighBitIdx = 52;
645 hasUnequalMargins = (floatExponent != 1) && (floatMantissa == 0);
646 }
647 else
648 {
649 // subnormal
650 // The floating point equation is:
651 // value = (mantissa/2^52) * 2 ^ (1-1023)
652 // We convert the integer equation by factoring a 2^52 out of the exponent
653 // value = (mantissa/2^52) * 2^52 * 2 ^ (1-1023-52)
654 // value = mantissa * 2 ^ (1-1023-52)
655 // We have up to 52 bits of precision.
656 // m = (mantissa)
657 // e = (1-1023-52)
658 mantissa = floatMantissa;
659 exponent = 1 - 1023 - 52;
660 mantissaHighBitIdx = LogBase2(mantissa);
661 hasUnequalMargins = false;
662 }
663
664 // format the value
665 switch (format)
666 {
667 case PrintFloatFormat_Positional:
668 return FormatPositional( pOutBuffer,
669 bufferSize,
670 mantissa,
671 exponent,
672 mantissaHighBitIdx,
673 hasUnequalMargins,
674 precision,
675 decimalPoint );
676
677 case PrintFloatFormat_Scientific:
678 return FormatScientific( pOutBuffer,
679 bufferSize,
680 mantissa,
681 exponent,
682 mantissaHighBitIdx,
683 hasUnequalMargins,
684 precision,
685 decimalPoint );
686
687 default:
688 pOutBuffer[0] = '\0';
689 return 0;
690 }
691 }
692}
diff --git a/scan-build/report-4b20f3.html b/scan-build/report-4b20f3.html deleted file mode 100644 index 2f89ec68..00000000 --- a/scan-build/report-4b20f3.html +++ /dev/null @@ -1,464 +0,0 @@ - - - -lib/real/kremp2.c - - - - - - - - - - - - - - - - - - - - - - - - - -

Bug Summary

- - - - -
File:real/kremp2.c
Location:line 307, column 18
Description:The right operand of '*' is a garbage value
- -

Annotated Source Code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/* @(#)k_rem_pio2.c 1.3 95/01/18 */
2
3/*
4 * Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * The origin source code can be obtained from:
28 * http://www.netlib.org/fdlibm/k_rem_pio2.c
29 *
30 */
31
32/*
33 * ====================================================
34 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
35 *
36 * Developed at SunSoft, a Sun Microsystems, Inc. business.
37 * Permission to use, copy, modify, and distribute this
38 * software is freely granted, provided that this notice
39 * is preserved.
40 * ====================================================
41 */
42
43#include "prim.h"
44#include "math.h"
45
46/*
47 * Constants:
48 * The hexadecimal values are the intended ones for the following
49 * constants. The decimal values may be used, provided that the
50 * compiler will convert from decimal to binary accurately enough
51 * to produce the hexadecimal values shown.
52 */
53
54static const int init_jk[] = {2,3,4,6}; /* initial value for jk */
55
56static const double PIo2[] = {
57 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
58 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
59 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
60 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
61 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
62 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
63 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
64 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
65};
66
67static const double
68zero = 0.0,
69one = 1.0,
70two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
71twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
72
73/**
74 * @brief Kernel reduction function.
75 * @version 1.4
76 * @date 96/03/07
77 * @details
78 * <pre>
79 * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
80 * double x[],y[]; int e0,nx,prec; int ipio2[];
81 *
82 * __kernel_rem_pio2 return the last three digits of N with
83 * y = x - N*pi/2
84 * so that |y| < pi/2.
85 *
86 * The method is to compute the integer (mod 8) and fraction parts of
87 * (2/pi)*x without doing the full multiplication. In general we
88 * skip the part of the product that are known to be a huge integer (
89 * more accurately, = 0 mod 8 ). Thus the number of operations are
90 * independent of the exponent of the input.
91 *
92 * (2/pi) is represented by an array of 24-bit integers in ipio2[].
93 *
94 * Input parameters:
95 * x[] The input value (must be positive) is broken into nx
96 * pieces of 24-bit integers in double precision format.
97 * x[i] will be the i-th 24 bit of x. The scaled exponent
98 * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
99 * match x's up to 24 bits.
100 *
101 * Example of breaking a double positive z into x[0]+x[1]+x[2]:
102 * e0 = ilogb(z)-23
103 * z = scalbn(z,-e0)
104 * for i = 0,1,2
105 * x[i] = floor(z)
106 * z = (z-x[i])*2**24
107 *
108 *
109 * y[] ouput result in an array of double precision numbers.
110 * The dimension of y[] is:
111 * 24-bit precision 1
112 * 53-bit precision 2
113 * 64-bit precision 2
114 * 113-bit precision 3
115 * The actual value is the sum of them. Thus for 113-bit
116 * precison, one may have to do something like:
117 *
118 * long double t,w,r_head, r_tail;
119 * t = (long double)y[2] + (long double)y[1];
120 * w = (long double)y[0];
121 * r_head = t+w;
122 * r_tail = w - (r_head - t);
123 *
124 * e0 The exponent of x[0]
125 *
126 * nx dimension of x[]
127 *
128 * prec an integer indicating the precision:
129 * 0 24 bits (single)
130 * 1 53 bits (double)
131 * 2 64 bits (extended)
132 * 3 113 bits (quad)
133 *
134 * ipio2[]
135 * integer array, contains the (24*i)-th to (24*i+23)-th
136 * bit of 2/pi after binary point. The corresponding
137 * floating value is
138 *
139 * ipio2[i] * 2^(-24(i+1)).
140 *
141 * External function:
142 * double scalbn(), floor();
143 *
144 *
145 * Here is the description of some local variables:
146 *
147 * jk jk+1 is the initial number of terms of ipio2[] needed
148 * in the computation. The recommended value is 2,3,4,
149 * 6 for single, double, extended,and quad.
150 *
151 * jz local integer variable indicating the number of
152 * terms of ipio2[] used.
153 *
154 * jx nx - 1
155 *
156 * jv index for pointing to the suitable ipio2[] for the
157 * computation. In general, we want
158 * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
159 * is an integer. Thus
160 * e0-3-24*jv >= 0 or (e0-3)/24 >= jv
161 * Hence jv = max(0,(e0-3)/24).
162 *
163 * jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
164 *
165 * q[] double array with integral value, representing the
166 * 24-bits chunk of the product of x and 2/pi.
167 *
168 * q0 the corresponding exponent of q[0]. Note that the
169 * exponent for q[i] would be q0-24*i.
170 *
171 * PIo2[] double precision array, obtained by cutting pi/2
172 * into 24 bits chunks.
173 *
174 * f[] ipio2[] in floating point
175 *
176 * iq[] integer array by breaking up q[] in 24-bits chunk.
177 *
178 * fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
179 *
180 * ih integer. If >0 it indicates q[] is >= 0.5, hence
181 * it also indicates the *sign* of the result.
182 *
183 * </pre>
184 * @copyright Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
185 * @license Developed at SunSoft, a Sun Microsystems, Inc. business. Permission
186 * to use, copy, modify, and distribute this software is freely granted,
187 * provided that this notice is preserved.
188 */
189
190int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int *ipio2)
191{
192 int jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
193 double z,fw,f[20],fq[20],q[20];
194
195 /* initialize jk*/
196 jk = init_jk[prec];
197 jp = jk;
198
199 /* determine jx,jv,q0, note that 3>q0 */
200 jx = nx-1;
201 jv = (e0-3)/24;
202 if(jv<0) jv=0;
1
Assuming 'jv' is >= 0
2
Taking false branch
203 q0 = e0-24*(jv+1);
204
205 /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
206 j = jv-jx;
207 m = jx+jk;
208 for(i=0; i<=m; i++,j++) f[i] = (j<0)? zero : (double) ipio2[j];
3
Assuming 'i' is > 'm'
4
Loop condition is false. Execution continues on line 211
209
210 /* compute q[0],q[1],...q[jk] */
211 for (i=0; i<=jk; i++) {
5
Assuming 'i' is > 'jk'
6
Loop condition is false. Execution continues on line 216
212 for(j=0,fw=0.0; j<=jx; j++) fw += x[j]*f[jx+i-j];
213 q[i] = fw;
214 }
215
216 jz = jk;
217recompute:
218 /* distill q[] into iq[] reversingly */
219 for(i=0,j=jz,z=q[jz]; j>0; i++,j--) {
7
Loop condition is false. Execution continues on line 226
220 fw = (double)((int)(twon24* z));
221 iq[i] = (int)(z-two24*fw);
222 z = q[j-1]+fw;
223 }
224
225 /* compute n */
226 z = scalbn(z,q0); /* actual value of z */
227 z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */
228 n = (int) z;
229 z -= (double)n;
230 ih = 0;
231 if(q0>0) { /* need iq[jz-1] to determine n */
8
Assuming 'q0' is <= 0
9
Taking false branch
232 i = (iq[jz-1]>>(24-q0));
233 n += i;
234 iq[jz-1] -= i<<(24-q0);
235 ih = iq[jz-1]>>(23-q0);
236 }
237 else if(q0==0) ih = iq[jz-1]>>23;
10
Assuming 'q0' is not equal to 0
11
Taking false branch
238 else if(z>=0.5) ih=2;
12
Taking false branch
239
240 if(ih>0) { /* q > 0.5 */
13
Taking false branch
241 n += 1;
242 carry = 0;
243 for(i=0; i<jz ; i++) { /* compute 1-q */
244 j = iq[i];
245 if(carry==0) {
246 if(j!=0) {
247 carry = 1;
248 iq[i] = 0x1000000- j;
249 }
250 } else iq[i] = 0xffffff - j;
251 }
252 if(q0>0) { /* rare case: chance is 1 in 12 */
253 switch(q0) {
254 case 1:
255 iq[jz-1] &= 0x7fffff;
256 break;
257 case 2:
258 iq[jz-1] &= 0x3fffff;
259 break;
260 }
261 }
262 if(ih==2) {
263 z = one - z;
264 if(carry!=0) z -= scalbn(one,q0);
265 }
266 }
267
268 /* check if recomputation is needed */
269 if(z==zero) {
14
Taking false branch
270 j = 0;
271 for (i=jz-1; i>=jk; i--) j |= iq[i];
272 if(j==0) { /* need recomputation */
273 for(k=1; iq[jk-k]==0; k++); /* k = no. of terms needed */
274
275 for(i=jz+1; i<=jz+k; i++) { /* add q[jz+1] to q[jz+k] */
276 f[jx+i] = (double) ipio2[jv+i];
277 for(j=0,fw=0.0; j<=jx; j++) fw += x[j]*f[jx+i-j];
278 q[i] = fw;
279 }
280 jz += k;
281 goto recompute;
282 }
283 }
284
285 /* chop off zero terms */
286 if(z==0.0) {
15
Taking true branch
287 jz -= 1;
288 q0 -= 24;
289 while(iq[jz]==0) {
16
Loop condition is false. Execution continues on line 305
290 jz--;
291 q0-=24;
292 }
293 } else { /* break z into 24-bit if necessary */
294 z = scalbn(z,-q0);
295 if(z>=two24) {
296 fw = (double)((int)(twon24*z));
297 iq[jz] = (int)(z-two24*fw);
298 jz += 1;
299 q0 += 24;
300 iq[jz] = (int) fw;
301 } else iq[jz] = (int) z ;
302 }
303
304 /* convert integer "bit" chunk to floating-point value */
305 fw = scalbn(one,q0);
306 for(i=jz; i>=0; i--) {
17
Assuming 'i' is >= 0
18
Loop condition is true. Entering loop body
19
Loop condition is true. Entering loop body
307 q[i] = fw*(double)iq[i];
20
The right operand of '*' is a garbage value
308 fw*=twon24;
309 }
310
311 /* compute PIo2[0,...,jp]*q[jz,...,0] */
312 for(i=jz; i>=0; i--) {
313 for(fw=0.0,k=0; k<=jp&&k<=jz-i; k++) fw += PIo2[k]*q[i+k];
314 fq[jz-i] = fw;
315 }
316
317 /* compress fq[] into y[] */
318 switch(prec) {
319 case 0:
320 fw = 0.0;
321 for (i=jz; i>=0; i--) fw += fq[i];
322 y[0] = (ih==0)? fw: -fw;
323 break;
324 case 1:
325 case 2:
326 fw = 0.0;
327 for (i=jz; i>=0; i--) fw += fq[i];
328 y[0] = (ih==0)? fw: -fw;
329 fw = fq[0]-fw;
330 for (i=1; i<=jz; i++) fw += fq[i];
331 y[1] = (ih==0)? fw: -fw;
332 break;
333 case 3: /* painful */
334 for (i=jz; i>0; i--) {
335 fw = fq[i-1]+fq[i];
336 fq[i] += fq[i-1]-fw;
337 fq[i-1] = fw;
338 }
339 for (i=jz; i>1; i--) {
340 fw = fq[i-1]+fq[i];
341 fq[i] += fq[i-1]-fw;
342 fq[i-1] = fw;
343 }
344 for (fw=0.0,i=jz; i>=2; i--) fw += fq[i];
345 if(ih==0) {
346 y[0] = fq[0];
347 y[1] = fq[1];
348 y[2] = fw;
349 } else {
350 y[0] = -fq[0];
351 y[1] = -fq[1];
352 y[2] = -fw;
353 }
354 }
355 return n&7;
356}
diff --git a/scan-build/report-4fd7ba.html b/scan-build/report-4fd7ba.html deleted file mode 100644 index 461e7c84..00000000 --- a/scan-build/report-4fd7ba.html +++ /dev/null @@ -1,467 +0,0 @@ - - - -lib/real/kremp2.c - - - - - - - - - - - - - - - - - - - - - - - - - -

Bug Summary

- - - - -
File:real/kremp2.c
Location:line 329, column 19
Description:The left operand of '-' is a garbage value
- -

Annotated Source Code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/* @(#)k_rem_pio2.c 1.3 95/01/18 */
2
3/*
4 * Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * The origin source code can be obtained from:
28 * http://www.netlib.org/fdlibm/k_rem_pio2.c
29 *
30 */
31
32/*
33 * ====================================================
34 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
35 *
36 * Developed at SunSoft, a Sun Microsystems, Inc. business.
37 * Permission to use, copy, modify, and distribute this
38 * software is freely granted, provided that this notice
39 * is preserved.
40 * ====================================================
41 */
42
43#include "prim.h"
44#include "math.h"
45
46/*
47 * Constants:
48 * The hexadecimal values are the intended ones for the following
49 * constants. The decimal values may be used, provided that the
50 * compiler will convert from decimal to binary accurately enough
51 * to produce the hexadecimal values shown.
52 */
53
54static const int init_jk[] = {2,3,4,6}; /* initial value for jk */
55
56static const double PIo2[] = {
57 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
58 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
59 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
60 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
61 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
62 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
63 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
64 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
65};
66
67static const double
68zero = 0.0,
69one = 1.0,
70two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
71twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
72
73/**
74 * @brief Kernel reduction function.
75 * @version 1.4
76 * @date 96/03/07
77 * @details
78 * <pre>
79 * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
80 * double x[],y[]; int e0,nx,prec; int ipio2[];
81 *
82 * __kernel_rem_pio2 return the last three digits of N with
83 * y = x - N*pi/2
84 * so that |y| < pi/2.
85 *
86 * The method is to compute the integer (mod 8) and fraction parts of
87 * (2/pi)*x without doing the full multiplication. In general we
88 * skip the part of the product that are known to be a huge integer (
89 * more accurately, = 0 mod 8 ). Thus the number of operations are
90 * independent of the exponent of the input.
91 *
92 * (2/pi) is represented by an array of 24-bit integers in ipio2[].
93 *
94 * Input parameters:
95 * x[] The input value (must be positive) is broken into nx
96 * pieces of 24-bit integers in double precision format.
97 * x[i] will be the i-th 24 bit of x. The scaled exponent
98 * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
99 * match x's up to 24 bits.
100 *
101 * Example of breaking a double positive z into x[0]+x[1]+x[2]:
102 * e0 = ilogb(z)-23
103 * z = scalbn(z,-e0)
104 * for i = 0,1,2
105 * x[i] = floor(z)
106 * z = (z-x[i])*2**24
107 *
108 *
109 * y[] ouput result in an array of double precision numbers.
110 * The dimension of y[] is:
111 * 24-bit precision 1
112 * 53-bit precision 2
113 * 64-bit precision 2
114 * 113-bit precision 3
115 * The actual value is the sum of them. Thus for 113-bit
116 * precison, one may have to do something like:
117 *
118 * long double t,w,r_head, r_tail;
119 * t = (long double)y[2] + (long double)y[1];
120 * w = (long double)y[0];
121 * r_head = t+w;
122 * r_tail = w - (r_head - t);
123 *
124 * e0 The exponent of x[0]
125 *
126 * nx dimension of x[]
127 *
128 * prec an integer indicating the precision:
129 * 0 24 bits (single)
130 * 1 53 bits (double)
131 * 2 64 bits (extended)
132 * 3 113 bits (quad)
133 *
134 * ipio2[]
135 * integer array, contains the (24*i)-th to (24*i+23)-th
136 * bit of 2/pi after binary point. The corresponding
137 * floating value is
138 *
139 * ipio2[i] * 2^(-24(i+1)).
140 *
141 * External function:
142 * double scalbn(), floor();
143 *
144 *
145 * Here is the description of some local variables:
146 *
147 * jk jk+1 is the initial number of terms of ipio2[] needed
148 * in the computation. The recommended value is 2,3,4,
149 * 6 for single, double, extended,and quad.
150 *
151 * jz local integer variable indicating the number of
152 * terms of ipio2[] used.
153 *
154 * jx nx - 1
155 *
156 * jv index for pointing to the suitable ipio2[] for the
157 * computation. In general, we want
158 * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
159 * is an integer. Thus
160 * e0-3-24*jv >= 0 or (e0-3)/24 >= jv
161 * Hence jv = max(0,(e0-3)/24).
162 *
163 * jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
164 *
165 * q[] double array with integral value, representing the
166 * 24-bits chunk of the product of x and 2/pi.
167 *
168 * q0 the corresponding exponent of q[0]. Note that the
169 * exponent for q[i] would be q0-24*i.
170 *
171 * PIo2[] double precision array, obtained by cutting pi/2
172 * into 24 bits chunks.
173 *
174 * f[] ipio2[] in floating point
175 *
176 * iq[] integer array by breaking up q[] in 24-bits chunk.
177 *
178 * fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
179 *
180 * ih integer. If >0 it indicates q[] is >= 0.5, hence
181 * it also indicates the *sign* of the result.
182 *
183 * </pre>
184 * @copyright Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
185 * @license Developed at SunSoft, a Sun Microsystems, Inc. business. Permission
186 * to use, copy, modify, and distribute this software is freely granted,
187 * provided that this notice is preserved.
188 */
189
190int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int *ipio2)
191{
192 int jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
193 double z,fw,f[20],fq[20],q[20];
194
195 /* initialize jk*/
196 jk = init_jk[prec];
197 jp = jk;
198
199 /* determine jx,jv,q0, note that 3>q0 */
200 jx = nx-1;
201 jv = (e0-3)/24;
202 if(jv<0) jv=0;
1
Assuming 'jv' is >= 0
2
Taking false branch
203 q0 = e0-24*(jv+1);
204
205 /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
206 j = jv-jx;
207 m = jx+jk;
208 for(i=0; i<=m; i++,j++) f[i] = (j<0)? zero : (double) ipio2[j];
3
Assuming 'i' is > 'm'
4
Loop condition is false. Execution continues on line 211
209
210 /* compute q[0],q[1],...q[jk] */
211 for (i=0; i<=jk; i++) {
5
Assuming 'i' is > 'jk'
6
Loop condition is false. Execution continues on line 216
212 for(j=0,fw=0.0; j<=jx; j++) fw += x[j]*f[jx+i-j];
213 q[i] = fw;
214 }
215
216 jz = jk;
217recompute:
218 /* distill q[] into iq[] reversingly */
219 for(i=0,j=jz,z=q[jz]; j>0; i++,j--) {
7
Loop condition is false. Execution continues on line 226
220 fw = (double)((int)(twon24* z));
221 iq[i] = (int)(z-two24*fw);
222 z = q[j-1]+fw;
223 }
224
225 /* compute n */
226 z = scalbn(z,q0); /* actual value of z */
227 z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */
228 n = (int) z;
229 z -= (double)n;
230 ih = 0;
231 if(q0>0) { /* need iq[jz-1] to determine n */
8
Assuming 'q0' is <= 0
9
Taking false branch
232 i = (iq[jz-1]>>(24-q0));
233 n += i;
234 iq[jz-1] -= i<<(24-q0);
235 ih = iq[jz-1]>>(23-q0);
236 }
237 else if(q0==0) ih = iq[jz-1]>>23;
10
Assuming 'q0' is not equal to 0
11
Taking false branch
238 else if(z>=0.5) ih=2;
12
Taking false branch
239
240 if(ih>0) { /* q > 0.5 */
13
Taking false branch
241 n += 1;
242 carry = 0;
243 for(i=0; i<jz ; i++) { /* compute 1-q */
244 j = iq[i];
245 if(carry==0) {
246 if(j!=0) {
247 carry = 1;
248 iq[i] = 0x1000000- j;
249 }
250 } else iq[i] = 0xffffff - j;
251 }
252 if(q0>0) { /* rare case: chance is 1 in 12 */
253 switch(q0) {
254 case 1:
255 iq[jz-1] &= 0x7fffff;
256 break;
257 case 2:
258 iq[jz-1] &= 0x3fffff;
259 break;
260 }
261 }
262 if(ih==2) {
263 z = one - z;
264 if(carry!=0) z -= scalbn(one,q0);
265 }
266 }
267
268 /* check if recomputation is needed */
269 if(z==zero) {
14
Taking false branch
270 j = 0;
271 for (i=jz-1; i>=jk; i--) j |= iq[i];
272 if(j==0) { /* need recomputation */
273 for(k=1; iq[jk-k]==0; k++); /* k = no. of terms needed */
274
275 for(i=jz+1; i<=jz+k; i++) { /* add q[jz+1] to q[jz+k] */
276 f[jx+i] = (double) ipio2[jv+i];
277 for(j=0,fw=0.0; j<=jx; j++) fw += x[j]*f[jx+i-j];
278 q[i] = fw;
279 }
280 jz += k;
281 goto recompute;
282 }
283 }
284
285 /* chop off zero terms */
286 if(z==0.0) {
15
Taking true branch
287 jz -= 1;
288 q0 -= 24;
289 while(iq[jz]==0) {
16
Loop condition is false. Execution continues on line 305
290 jz--;
291 q0-=24;
292 }
293 } else { /* break z into 24-bit if necessary */
294 z = scalbn(z,-q0);
295 if(z>=two24) {
296 fw = (double)((int)(twon24*z));
297 iq[jz] = (int)(z-two24*fw);
298 jz += 1;
299 q0 += 24;
300 iq[jz] = (int) fw;
301 } else iq[jz] = (int) z ;
302 }
303
304 /* convert integer "bit" chunk to floating-point value */
305 fw = scalbn(one,q0);
306 for(i=jz; i>=0; i--) {
17
Assuming 'i' is < 0
18
Loop condition is false. Execution continues on line 312
307 q[i] = fw*(double)iq[i];
308 fw*=twon24;
309 }
310
311 /* compute PIo2[0,...,jp]*q[jz,...,0] */
312 for(i=jz; i>=0; i--) {
19
Loop condition is false. Execution continues on line 318
313 for(fw=0.0,k=0; k<=jp&&k<=jz-i; k++) fw += PIo2[k]*q[i+k];
314 fq[jz-i] = fw;
315 }
316
317 /* compress fq[] into y[] */
318 switch(prec) {
20
Control jumps to 'case 2:' at line 325
319 case 0:
320 fw = 0.0;
321 for (i=jz; i>=0; i--) fw += fq[i];
322 y[0] = (ih==0)? fw: -fw;
323 break;
324 case 1:
325 case 2:
326 fw = 0.0;
327 for (i=jz; i>=0; i--) fw += fq[i];
21
Loop condition is false. Execution continues on line 328
328 y[0] = (ih==0)? fw: -fw;
22
'?' condition is true
329 fw = fq[0]-fw;
23
The left operand of '-' is a garbage value
330 for (i=1; i<=jz; i++) fw += fq[i];
331 y[1] = (ih==0)? fw: -fw;
332 break;
333 case 3: /* painful */
334 for (i=jz; i>0; i--) {
335 fw = fq[i-1]+fq[i];
336 fq[i] += fq[i-1]-fw;
337 fq[i-1] = fw;
338 }
339 for (i=jz; i>1; i--) {
340 fw = fq[i-1]+fq[i];
341 fq[i] += fq[i-1]-fw;
342 fq[i-1] = fw;
343 }
344 for (fw=0.0,i=jz; i>=2; i--) fw += fq[i];
345 if(ih==0) {
346 y[0] = fq[0];
347 y[1] = fq[1];
348 y[2] = fw;
349 } else {
350 y[0] = -fq[0];
351 y[1] = -fq[1];
352 y[2] = -fw;
353 }
354 }
355 return n&7;
356}
diff --git a/scan-build/report-762445.html b/scan-build/report-762445.html deleted file mode 100644 index a96efeee..00000000 --- a/scan-build/report-762445.html +++ /dev/null @@ -1,467 +0,0 @@ - - - -lib/real/kremp2.c - - - - - - - - - - - - - - - - - - - - - - - - - -

Bug Summary

- - - - -
File:real/kremp2.c
Location:line 222, column 24
Description:The left operand of '+' is a garbage value
- -

Annotated Source Code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/* @(#)k_rem_pio2.c 1.3 95/01/18 */
2
3/*
4 * Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * The origin source code can be obtained from:
28 * http://www.netlib.org/fdlibm/k_rem_pio2.c
29 *
30 */
31
32/*
33 * ====================================================
34 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
35 *
36 * Developed at SunSoft, a Sun Microsystems, Inc. business.
37 * Permission to use, copy, modify, and distribute this
38 * software is freely granted, provided that this notice
39 * is preserved.
40 * ====================================================
41 */
42
43#include "prim.h"
44#include "math.h"
45
46/*
47 * Constants:
48 * The hexadecimal values are the intended ones for the following
49 * constants. The decimal values may be used, provided that the
50 * compiler will convert from decimal to binary accurately enough
51 * to produce the hexadecimal values shown.
52 */
53
54static const int init_jk[] = {2,3,4,6}; /* initial value for jk */
55
56static const double PIo2[] = {
57 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
58 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
59 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
60 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
61 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
62 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
63 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
64 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
65};
66
67static const double
68zero = 0.0,
69one = 1.0,
70two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
71twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
72
73/**
74 * @brief Kernel reduction function.
75 * @version 1.4
76 * @date 96/03/07
77 * @details
78 * <pre>
79 * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
80 * double x[],y[]; int e0,nx,prec; int ipio2[];
81 *
82 * __kernel_rem_pio2 return the last three digits of N with
83 * y = x - N*pi/2
84 * so that |y| < pi/2.
85 *
86 * The method is to compute the integer (mod 8) and fraction parts of
87 * (2/pi)*x without doing the full multiplication. In general we
88 * skip the part of the product that are known to be a huge integer (
89 * more accurately, = 0 mod 8 ). Thus the number of operations are
90 * independent of the exponent of the input.
91 *
92 * (2/pi) is represented by an array of 24-bit integers in ipio2[].
93 *
94 * Input parameters:
95 * x[] The input value (must be positive) is broken into nx
96 * pieces of 24-bit integers in double precision format.
97 * x[i] will be the i-th 24 bit of x. The scaled exponent
98 * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
99 * match x's up to 24 bits.
100 *
101 * Example of breaking a double positive z into x[0]+x[1]+x[2]:
102 * e0 = ilogb(z)-23
103 * z = scalbn(z,-e0)
104 * for i = 0,1,2
105 * x[i] = floor(z)
106 * z = (z-x[i])*2**24
107 *
108 *
109 * y[] ouput result in an array of double precision numbers.
110 * The dimension of y[] is:
111 * 24-bit precision 1
112 * 53-bit precision 2
113 * 64-bit precision 2
114 * 113-bit precision 3
115 * The actual value is the sum of them. Thus for 113-bit
116 * precison, one may have to do something like:
117 *
118 * long double t,w,r_head, r_tail;
119 * t = (long double)y[2] + (long double)y[1];
120 * w = (long double)y[0];
121 * r_head = t+w;
122 * r_tail = w - (r_head - t);
123 *
124 * e0 The exponent of x[0]
125 *
126 * nx dimension of x[]
127 *
128 * prec an integer indicating the precision:
129 * 0 24 bits (single)
130 * 1 53 bits (double)
131 * 2 64 bits (extended)
132 * 3 113 bits (quad)
133 *
134 * ipio2[]
135 * integer array, contains the (24*i)-th to (24*i+23)-th
136 * bit of 2/pi after binary point. The corresponding
137 * floating value is
138 *
139 * ipio2[i] * 2^(-24(i+1)).
140 *
141 * External function:
142 * double scalbn(), floor();
143 *
144 *
145 * Here is the description of some local variables:
146 *
147 * jk jk+1 is the initial number of terms of ipio2[] needed
148 * in the computation. The recommended value is 2,3,4,
149 * 6 for single, double, extended,and quad.
150 *
151 * jz local integer variable indicating the number of
152 * terms of ipio2[] used.
153 *
154 * jx nx - 1
155 *
156 * jv index for pointing to the suitable ipio2[] for the
157 * computation. In general, we want
158 * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
159 * is an integer. Thus
160 * e0-3-24*jv >= 0 or (e0-3)/24 >= jv
161 * Hence jv = max(0,(e0-3)/24).
162 *
163 * jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
164 *
165 * q[] double array with integral value, representing the
166 * 24-bits chunk of the product of x and 2/pi.
167 *
168 * q0 the corresponding exponent of q[0]. Note that the
169 * exponent for q[i] would be q0-24*i.
170 *
171 * PIo2[] double precision array, obtained by cutting pi/2
172 * into 24 bits chunks.
173 *
174 * f[] ipio2[] in floating point
175 *
176 * iq[] integer array by breaking up q[] in 24-bits chunk.
177 *
178 * fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
179 *
180 * ih integer. If >0 it indicates q[] is >= 0.5, hence
181 * it also indicates the *sign* of the result.
182 *
183 * </pre>
184 * @copyright Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
185 * @license Developed at SunSoft, a Sun Microsystems, Inc. business. Permission
186 * to use, copy, modify, and distribute this software is freely granted,
187 * provided that this notice is preserved.
188 */
189
190int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int *ipio2)
191{
192 int jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
193 double z,fw,f[20],fq[20],q[20];
194
195 /* initialize jk*/
196 jk = init_jk[prec];
197 jp = jk;
198
199 /* determine jx,jv,q0, note that 3>q0 */
200 jx = nx-1;
201 jv = (e0-3)/24;
202 if(jv<0) jv=0;
1
Assuming 'jv' is >= 0
2
Taking false branch
203 q0 = e0-24*(jv+1);
204
205 /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
206 j = jv-jx;
207 m = jx+jk;
208 for(i=0; i<=m; i++,j++) f[i] = (j<0)? zero : (double) ipio2[j];
3
Assuming 'i' is > 'm'
4
Loop condition is false. Execution continues on line 211
209
210 /* compute q[0],q[1],...q[jk] */
211 for (i=0; i<=jk; i++) {
5
Assuming 'i' is > 'jk'
6
Loop condition is false. Execution continues on line 216
212 for(j=0,fw=0.0; j<=jx; j++) fw += x[j]*f[jx+i-j];
213 q[i] = fw;
214 }
215
216 jz = jk;
217recompute:
218 /* distill q[] into iq[] reversingly */
219 for(i=0,j=jz,z=q[jz]; j>0; i++,j--) {
7
Loop condition is false. Execution continues on line 226
21
Assuming 'j' is > 0
22
Loop condition is true. Entering loop body
220 fw = (double)((int)(twon24* z));
221 iq[i] = (int)(z-two24*fw);
222 z = q[j-1]+fw;
23
The left operand of '+' is a garbage value
223 }
224
225 /* compute n */
226 z = scalbn(z,q0); /* actual value of z */
227 z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */
228 n = (int) z;
229 z -= (double)n;
230 ih = 0;
231 if(q0>0) { /* need iq[jz-1] to determine n */
8
Assuming 'q0' is <= 0
9
Taking false branch
232 i = (iq[jz-1]>>(24-q0));
233 n += i;
234 iq[jz-1] -= i<<(24-q0);
235 ih = iq[jz-1]>>(23-q0);
236 }
237 else if(q0==0) ih = iq[jz-1]>>23;
10
Assuming 'q0' is not equal to 0
11
Taking false branch
238 else if(z>=0.5) ih=2;
12
Taking false branch
239
240 if(ih>0) { /* q > 0.5 */
13
Taking false branch
241 n += 1;
242 carry = 0;
243 for(i=0; i<jz ; i++) { /* compute 1-q */
244 j = iq[i];
245 if(carry==0) {
246 if(j!=0) {
247 carry = 1;
248 iq[i] = 0x1000000- j;
249 }
250 } else iq[i] = 0xffffff - j;
251 }
252 if(q0>0) { /* rare case: chance is 1 in 12 */
253 switch(q0) {
254 case 1:
255 iq[jz-1] &= 0x7fffff;
256 break;
257 case 2:
258 iq[jz-1] &= 0x3fffff;
259 break;
260 }
261 }
262 if(ih==2) {
263 z = one - z;
264 if(carry!=0) z -= scalbn(one,q0);
265 }
266 }
267
268 /* check if recomputation is needed */
269 if(z==zero) {
14
Taking true branch
270 j = 0;
271 for (i=jz-1; i>=jk; i--) j |= iq[i];
15
Loop condition is false. Execution continues on line 272
272 if(j==0) { /* need recomputation */
16
Taking true branch
273 for(k=1; iq[jk-k]==0; k++); /* k = no. of terms needed */
17
Loop condition is true. Entering loop body
18
Loop condition is false. Execution continues on line 275
274
275 for(i=jz+1; i<=jz+k; i++) { /* add q[jz+1] to q[jz+k] */
19
Loop condition is false. Execution continues on line 280
276 f[jx+i] = (double) ipio2[jv+i];
277 for(j=0,fw=0.0; j<=jx; j++) fw += x[j]*f[jx+i-j];
278 q[i] = fw;
279 }
280 jz += k;
281 goto recompute;
20
Control jumps to line 219
282 }
283 }
284
285 /* chop off zero terms */
286 if(z==0.0) {
287 jz -= 1;
288 q0 -= 24;
289 while(iq[jz]==0) {
290 jz--;
291 q0-=24;
292 }
293 } else { /* break z into 24-bit if necessary */
294 z = scalbn(z,-q0);
295 if(z>=two24) {
296 fw = (double)((int)(twon24*z));
297 iq[jz] = (int)(z-two24*fw);
298 jz += 1;
299 q0 += 24;
300 iq[jz] = (int) fw;
301 } else iq[jz] = (int) z ;
302 }
303
304 /* convert integer "bit" chunk to floating-point value */
305 fw = scalbn(one,q0);
306 for(i=jz; i>=0; i--) {
307 q[i] = fw*(double)iq[i];
308 fw*=twon24;
309 }
310
311 /* compute PIo2[0,...,jp]*q[jz,...,0] */
312 for(i=jz; i>=0; i--) {
313 for(fw=0.0,k=0; k<=jp&&k<=jz-i; k++) fw += PIo2[k]*q[i+k];
314 fq[jz-i] = fw;
315 }
316
317 /* compress fq[] into y[] */
318 switch(prec) {
319 case 0:
320 fw = 0.0;
321 for (i=jz; i>=0; i--) fw += fq[i];
322 y[0] = (ih==0)? fw: -fw;
323 break;
324 case 1:
325 case 2:
326 fw = 0.0;
327 for (i=jz; i>=0; i--) fw += fq[i];
328 y[0] = (ih==0)? fw: -fw;
329 fw = fq[0]-fw;
330 for (i=1; i<=jz; i++) fw += fq[i];
331 y[1] = (ih==0)? fw: -fw;
332 break;
333 case 3: /* painful */
334 for (i=jz; i>0; i--) {
335 fw = fq[i-1]+fq[i];
336 fq[i] += fq[i-1]-fw;
337 fq[i-1] = fw;
338 }
339 for (i=jz; i>1; i--) {
340 fw = fq[i-1]+fq[i];
341 fq[i] += fq[i-1]-fw;
342 fq[i-1] = fw;
343 }
344 for (fw=0.0,i=jz; i>=2; i--) fw += fq[i];
345 if(ih==0) {
346 y[0] = fq[0];
347 y[1] = fq[1];
348 y[2] = fw;
349 } else {
350 y[0] = -fq[0];
351 y[1] = -fq[1];
352 y[2] = -fw;
353 }
354 }
355 return n&7;
356}
diff --git a/scan-build/report-831a75.html b/scan-build/report-831a75.html deleted file mode 100644 index 1049a72a..00000000 --- a/scan-build/report-831a75.html +++ /dev/null @@ -1,469 +0,0 @@ - - - -lib/real/kremp2.c - - - - - - - - - - - - - - - - - - - - - - - - - -

Bug Summary

- - - - -
File:real/kremp2.c
Location:line 346, column 18
Description:Assigned value is garbage or undefined
- -

Annotated Source Code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/* @(#)k_rem_pio2.c 1.3 95/01/18 */
2
3/*
4 * Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * The origin source code can be obtained from:
28 * http://www.netlib.org/fdlibm/k_rem_pio2.c
29 *
30 */
31
32/*
33 * ====================================================
34 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
35 *
36 * Developed at SunSoft, a Sun Microsystems, Inc. business.
37 * Permission to use, copy, modify, and distribute this
38 * software is freely granted, provided that this notice
39 * is preserved.
40 * ====================================================
41 */
42
43#include "prim.h"
44#include "math.h"
45
46/*
47 * Constants:
48 * The hexadecimal values are the intended ones for the following
49 * constants. The decimal values may be used, provided that the
50 * compiler will convert from decimal to binary accurately enough
51 * to produce the hexadecimal values shown.
52 */
53
54static const int init_jk[] = {2,3,4,6}; /* initial value for jk */
55
56static const double PIo2[] = {
57 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
58 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
59 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
60 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
61 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
62 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
63 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
64 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
65};
66
67static const double
68zero = 0.0,
69one = 1.0,
70two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
71twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
72
73/**
74 * @brief Kernel reduction function.
75 * @version 1.4
76 * @date 96/03/07
77 * @details
78 * <pre>
79 * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
80 * double x[],y[]; int e0,nx,prec; int ipio2[];
81 *
82 * __kernel_rem_pio2 return the last three digits of N with
83 * y = x - N*pi/2
84 * so that |y| < pi/2.
85 *
86 * The method is to compute the integer (mod 8) and fraction parts of
87 * (2/pi)*x without doing the full multiplication. In general we
88 * skip the part of the product that are known to be a huge integer (
89 * more accurately, = 0 mod 8 ). Thus the number of operations are
90 * independent of the exponent of the input.
91 *
92 * (2/pi) is represented by an array of 24-bit integers in ipio2[].
93 *
94 * Input parameters:
95 * x[] The input value (must be positive) is broken into nx
96 * pieces of 24-bit integers in double precision format.
97 * x[i] will be the i-th 24 bit of x. The scaled exponent
98 * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
99 * match x's up to 24 bits.
100 *
101 * Example of breaking a double positive z into x[0]+x[1]+x[2]:
102 * e0 = ilogb(z)-23
103 * z = scalbn(z,-e0)
104 * for i = 0,1,2
105 * x[i] = floor(z)
106 * z = (z-x[i])*2**24
107 *
108 *
109 * y[] ouput result in an array of double precision numbers.
110 * The dimension of y[] is:
111 * 24-bit precision 1
112 * 53-bit precision 2
113 * 64-bit precision 2
114 * 113-bit precision 3
115 * The actual value is the sum of them. Thus for 113-bit
116 * precison, one may have to do something like:
117 *
118 * long double t,w,r_head, r_tail;
119 * t = (long double)y[2] + (long double)y[1];
120 * w = (long double)y[0];
121 * r_head = t+w;
122 * r_tail = w - (r_head - t);
123 *
124 * e0 The exponent of x[0]
125 *
126 * nx dimension of x[]
127 *
128 * prec an integer indicating the precision:
129 * 0 24 bits (single)
130 * 1 53 bits (double)
131 * 2 64 bits (extended)
132 * 3 113 bits (quad)
133 *
134 * ipio2[]
135 * integer array, contains the (24*i)-th to (24*i+23)-th
136 * bit of 2/pi after binary point. The corresponding
137 * floating value is
138 *
139 * ipio2[i] * 2^(-24(i+1)).
140 *
141 * External function:
142 * double scalbn(), floor();
143 *
144 *
145 * Here is the description of some local variables:
146 *
147 * jk jk+1 is the initial number of terms of ipio2[] needed
148 * in the computation. The recommended value is 2,3,4,
149 * 6 for single, double, extended,and quad.
150 *
151 * jz local integer variable indicating the number of
152 * terms of ipio2[] used.
153 *
154 * jx nx - 1
155 *
156 * jv index for pointing to the suitable ipio2[] for the
157 * computation. In general, we want
158 * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
159 * is an integer. Thus
160 * e0-3-24*jv >= 0 or (e0-3)/24 >= jv
161 * Hence jv = max(0,(e0-3)/24).
162 *
163 * jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
164 *
165 * q[] double array with integral value, representing the
166 * 24-bits chunk of the product of x and 2/pi.
167 *
168 * q0 the corresponding exponent of q[0]. Note that the
169 * exponent for q[i] would be q0-24*i.
170 *
171 * PIo2[] double precision array, obtained by cutting pi/2
172 * into 24 bits chunks.
173 *
174 * f[] ipio2[] in floating point
175 *
176 * iq[] integer array by breaking up q[] in 24-bits chunk.
177 *
178 * fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
179 *
180 * ih integer. If >0 it indicates q[] is >= 0.5, hence
181 * it also indicates the *sign* of the result.
182 *
183 * </pre>
184 * @copyright Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
185 * @license Developed at SunSoft, a Sun Microsystems, Inc. business. Permission
186 * to use, copy, modify, and distribute this software is freely granted,
187 * provided that this notice is preserved.
188 */
189
190int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int *ipio2)
191{
192 int jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
193 double z,fw,f[20],fq[20],q[20];
194
195 /* initialize jk*/
196 jk = init_jk[prec];
197 jp = jk;
198
199 /* determine jx,jv,q0, note that 3>q0 */
200 jx = nx-1;
201 jv = (e0-3)/24;
202 if(jv<0) jv=0;
1
Assuming 'jv' is >= 0
2
Taking false branch
203 q0 = e0-24*(jv+1);
204
205 /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
206 j = jv-jx;
207 m = jx+jk;
208 for(i=0; i<=m; i++,j++) f[i] = (j<0)? zero : (double) ipio2[j];
3
Assuming 'i' is > 'm'
4
Loop condition is false. Execution continues on line 211
209
210 /* compute q[0],q[1],...q[jk] */
211 for (i=0; i<=jk; i++) {
5
Assuming 'i' is > 'jk'
6
Loop condition is false. Execution continues on line 216
212 for(j=0,fw=0.0; j<=jx; j++) fw += x[j]*f[jx+i-j];
213 q[i] = fw;
214 }
215
216 jz = jk;
217recompute:
218 /* distill q[] into iq[] reversingly */
219 for(i=0,j=jz,z=q[jz]; j>0; i++,j--) {
7
Loop condition is false. Execution continues on line 226
220 fw = (double)((int)(twon24* z));
221 iq[i] = (int)(z-two24*fw);
222 z = q[j-1]+fw;
223 }
224
225 /* compute n */
226 z = scalbn(z,q0); /* actual value of z */
227 z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */
228 n = (int) z;
229 z -= (double)n;
230 ih = 0;
231 if(q0>0) { /* need iq[jz-1] to determine n */
8
Assuming 'q0' is <= 0
9
Taking false branch
232 i = (iq[jz-1]>>(24-q0));
233 n += i;
234 iq[jz-1] -= i<<(24-q0);
235 ih = iq[jz-1]>>(23-q0);
236 }
237 else if(q0==0) ih = iq[jz-1]>>23;
10
Assuming 'q0' is not equal to 0
11
Taking false branch
238 else if(z>=0.5) ih=2;
12
Taking false branch
239
240 if(ih>0) { /* q > 0.5 */
13
Taking false branch
241 n += 1;
242 carry = 0;
243 for(i=0; i<jz ; i++) { /* compute 1-q */
244 j = iq[i];
245 if(carry==0) {
246 if(j!=0) {
247 carry = 1;
248 iq[i] = 0x1000000- j;
249 }
250 } else iq[i] = 0xffffff - j;
251 }
252 if(q0>0) { /* rare case: chance is 1 in 12 */
253 switch(q0) {
254 case 1:
255 iq[jz-1] &= 0x7fffff;
256 break;
257 case 2:
258 iq[jz-1] &= 0x3fffff;
259 break;
260 }
261 }
262 if(ih==2) {
263 z = one - z;
264 if(carry!=0) z -= scalbn(one,q0);
265 }
266 }
267
268 /* check if recomputation is needed */
269 if(z==zero) {
14
Taking false branch
270 j = 0;
271 for (i=jz-1; i>=jk; i--) j |= iq[i];
272 if(j==0) { /* need recomputation */
273 for(k=1; iq[jk-k]==0; k++); /* k = no. of terms needed */
274
275 for(i=jz+1; i<=jz+k; i++) { /* add q[jz+1] to q[jz+k] */
276 f[jx+i] = (double) ipio2[jv+i];
277 for(j=0,fw=0.0; j<=jx; j++) fw += x[j]*f[jx+i-j];
278 q[i] = fw;
279 }
280 jz += k;
281 goto recompute;
282 }
283 }
284
285 /* chop off zero terms */
286 if(z==0.0) {
15
Taking true branch
287 jz -= 1;
288 q0 -= 24;
289 while(iq[jz]==0) {
16
Loop condition is false. Execution continues on line 305
290 jz--;
291 q0-=24;
292 }
293 } else { /* break z into 24-bit if necessary */
294 z = scalbn(z,-q0);
295 if(z>=two24) {
296 fw = (double)((int)(twon24*z));
297 iq[jz] = (int)(z-two24*fw);
298 jz += 1;
299 q0 += 24;
300 iq[jz] = (int) fw;
301 } else iq[jz] = (int) z ;
302 }
303
304 /* convert integer "bit" chunk to floating-point value */
305 fw = scalbn(one,q0);
306 for(i=jz; i>=0; i--) {
17
Assuming 'i' is < 0
18
Loop condition is false. Execution continues on line 312
307 q[i] = fw*(double)iq[i];
308 fw*=twon24;
309 }
310
311 /* compute PIo2[0,...,jp]*q[jz,...,0] */
312 for(i=jz; i>=0; i--) {
19
Loop condition is false. Execution continues on line 318
313 for(fw=0.0,k=0; k<=jp&&k<=jz-i; k++) fw += PIo2[k]*q[i+k];
314 fq[jz-i] = fw;
315 }
316
317 /* compress fq[] into y[] */
318 switch(prec) {
20
Control jumps to 'case 3:' at line 333
319 case 0:
320 fw = 0.0;
321 for (i=jz; i>=0; i--) fw += fq[i];
322 y[0] = (ih==0)? fw: -fw;
323 break;
324 case 1:
325 case 2:
326 fw = 0.0;
327 for (i=jz; i>=0; i--) fw += fq[i];
328 y[0] = (ih==0)? fw: -fw;
329 fw = fq[0]-fw;
330 for (i=1; i<=jz; i++) fw += fq[i];
331 y[1] = (ih==0)? fw: -fw;
332 break;
333 case 3: /* painful */
334 for (i=jz; i>0; i--) {
21
Loop condition is false. Execution continues on line 339
335 fw = fq[i-1]+fq[i];
336 fq[i] += fq[i-1]-fw;
337 fq[i-1] = fw;
338 }
339 for (i=jz; i>1; i--) {
22
Loop condition is false. Execution continues on line 344
340 fw = fq[i-1]+fq[i];
341 fq[i] += fq[i-1]-fw;
342 fq[i-1] = fw;
343 }
344 for (fw=0.0,i=jz; i>=2; i--) fw += fq[i];
23
Loop condition is false. Execution continues on line 345
345 if(ih==0) {
24
Taking true branch
346 y[0] = fq[0];
25
Assigned value is garbage or undefined
347 y[1] = fq[1];
348 y[2] = fw;
349 } else {
350 y[0] = -fq[0];
351 y[1] = -fq[1];
352 y[2] = -fw;
353 }
354 }
355 return n&7;
356}
diff --git a/scan-build/report-a2ee02.html b/scan-build/report-a2ee02.html deleted file mode 100644 index 1523f60b..00000000 --- a/scan-build/report-a2ee02.html +++ /dev/null @@ -1,1273 +0,0 @@ - - - -lib/dconv/dragon4.cpp - - - - - - - - - - - - - - - - - - - - - - - - - -

Bug Summary

- - - - -
File:dconv/dragon4.cpp
Location:line 702, column 22
Description:Assigned value is garbage or undefined
- -

Annotated Source Code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/******************************************************************************
2 Copyright (c) 2014 Ryan Juckett
3 http://www.ryanjuckett.com/
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20
21 3. This notice may not be removed or altered from any source
22 distribution.
23*******************************************************************************
24 Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
25 All rights reserved.
26
27 Redistribution and use in source and binary forms, with or without
28 modification, are permitted provided that the following conditions
29 are met:
30 1. Redistributions of source code must retain the above copyright
31 notice, this list of conditions and the following disclaimer.
32
33 2. Redistributions in binary form must reproduce the above copyright
34 notice, this list of conditions and the following disclaimer in the
35 documentation and/or other materials provided with the distribution.
36
37 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
38 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
40 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
41 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
46 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47
48 The origin source code can be obtained from:
49 http://www.ryanjuckett.com/
50
51******************************************************************************/
52
53#include "math.h"
54#include "dmath.h"
55#include "dragon4.h"
56
57//******************************************************************************
58// Maximum number of 32 bit blocks needed in high precision arithmetic
59// to print out 64 bit IEEE floating point values.
60//******************************************************************************
61const tU32 c_BigInt_MaxBlocks = 35;
62
63//******************************************************************************
64// This structure stores a high precision unsigned integer. It uses a buffer
65// of 32 bit integer blocks along with a length. The lowest bits of the integer
66// are stored at the start of the buffer and the length is set to the minimum
67// value that contains the integer. Thus, there are never any zero blocks at the
68// end of the buffer.
69//******************************************************************************
70struct tBigInt
71{
72 // Copy integer
73 tBigInt & operator=(const tBigInt &rhs)
74 {
75 tU32 length = rhs.m_length;
76 tU32 * pLhsCur = m_blocks;
77 for (const tU32 *pRhsCur = rhs.m_blocks, *pRhsEnd = pRhsCur + length;
78 pRhsCur != pRhsEnd;
79 ++pLhsCur, ++pRhsCur)
80 {
81 *pLhsCur = *pRhsCur;
82 }
83 m_length = length;
84 return *this;
85 }
86
87 // Data accessors
88 tU32 GetLength() const {
89 return m_length;
90 }
91 tU32 GetBlock(tU32 idx) const {
92 return m_blocks[idx];
93 }
94
95 // Zero helper functions
96 void SetZero() {
97 m_length = 0;
98 }
99 tB IsZero() const {
100 return m_length == 0;
101 }
102
103 // Basic type accessors
104 void SetU64(tU64 val)
105 {
106 if (val > 0xFFFFFFFF)
107 {
108 m_blocks[0] = val & 0xFFFFFFFF;
109 m_blocks[1] = (val >> 32) & 0xFFFFFFFF;
110 m_length = 2;
111 }
112 else if (val != 0)
113 {
114 m_blocks[0] = val & 0xFFFFFFFF;
115 m_length = 1;
116 }
117 else
118 {
119 m_length = 0;
120 }
121 }
122
123 void SetU32(tU32 val)
124 {
125 if (val != 0)
126 {
127 m_blocks[0] = val;
128 m_length = (val != 0);
129 }
130 else
131 {
132 m_length = 0;
133 }
134 }
135
136 tU32 GetU32() const {
137 return (m_length == 0) ? 0 : m_blocks[0];
138 }
139
140 // Member data
141 tU32 m_length;
142 tU32 m_blocks[c_BigInt_MaxBlocks];
143};
144
145//******************************************************************************
146// Returns 0 if (lhs = rhs), negative if (lhs < rhs), positive if (lhs > rhs)
147//******************************************************************************
148static tS32 BigInt_Compare(const tBigInt & lhs, const tBigInt & rhs)
149{
150 // A bigger length implies a bigger number.
151 tS32 lengthDiff = lhs.m_length - rhs.m_length;
152 if (lengthDiff != 0)
153 return lengthDiff;
154
155 // Compare blocks one by one from high to low.
156 for (tS32 i = lhs.m_length - 1; i >= 0; --i)
157 {
158 if (lhs.m_blocks[i] == rhs.m_blocks[i])
159 continue;
160 else if (lhs.m_blocks[i] > rhs.m_blocks[i])
161 return 1;
162 else
163 return -1;
164 }
165
166 // no blocks differed
167 return 0;
168}
169
170//******************************************************************************
171// result = lhs + rhs
172//******************************************************************************
173static void BigInt_Add(tBigInt * pResult, const tBigInt & lhs, const tBigInt & rhs)
174{
175 // determine which operand has the smaller length
176 const tBigInt * pLarge;
177 const tBigInt * pSmall;
178 if (lhs.m_length < rhs.m_length)
179 {
180 pSmall = &lhs;
181 pLarge = &rhs;
182 }
183 else
184 {
185 pSmall = &rhs;
186 pLarge = &lhs;
187 }
188
189 const tU32 largeLen = pLarge->m_length;
190 const tU32 smallLen = pSmall->m_length;
191
192 // The output will be at least as long as the largest input
193 pResult->m_length = largeLen;
194
195 // Add each block and add carry the overflow to the next block
196 tU64 carry = 0;
197 const tU32 * pLargeCur = pLarge->m_blocks;
198 const tU32 * pLargeEnd = pLargeCur + largeLen;
199 const tU32 * pSmallCur = pSmall->m_blocks;
200 const tU32 * pSmallEnd = pSmallCur + smallLen;
201 tU32 * pResultCur = pResult->m_blocks;
202 while (pSmallCur != pSmallEnd)
203 {
204 tU64 sum = carry + (tU64)(*pLargeCur) + (tU64)(*pSmallCur);
205 carry = sum >> 32;
206 (*pResultCur) = sum & 0xFFFFFFFF;
207 ++pLargeCur;
208 ++pSmallCur;
209 ++pResultCur;
210 }
211
212 // Add the carry to any blocks that only exist in the large operand
213 while (pLargeCur != pLargeEnd)
214 {
215 tU64 sum = carry + (tU64)(*pLargeCur);
216 carry = sum >> 32;
217 (*pResultCur) = sum & 0xFFFFFFFF;
218 ++pLargeCur;
219 ++pResultCur;
220 }
221
222 // If there's still a carry, append a new block
223 if (carry != 0)
224 {
225 RJ_ASSERT(carry == 1);
226 RJ_ASSERT((tU32)(pResultCur - pResult->m_blocks) == largeLen && (largeLen < c_BigInt_MaxBlocks));
227 *pResultCur = 1;
228 pResult->m_length = largeLen + 1;
229 }
230 else
231 {
232 pResult->m_length = largeLen;
233 }
234}
235
236//******************************************************************************
237// result = lhs * rhs
238//******************************************************************************
239static void BigInt_Multiply(tBigInt * pResult, const tBigInt &lhs, const tBigInt &rhs)
240{
241 RJ_ASSERT( pResult != &lhs && pResult != &rhs );
242
243 // determine which operand has the smaller length
244 const tBigInt * pLarge;
245 const tBigInt * pSmall;
246 if (lhs.m_length < rhs.m_length)
247 {
248 pSmall = &lhs;
249 pLarge = &rhs;
250 }
251 else
252 {
253 pSmall = &rhs;
254 pLarge = &lhs;
255 }
256
257 // set the maximum possible result length
258 tU32 maxResultLen = pLarge->m_length + pSmall->m_length;
259 RJ_ASSERT( maxResultLen <= c_BigInt_MaxBlocks );
260
261 // clear the result data
262 for(tU32 * pCur = pResult->m_blocks, *pEnd = pCur + maxResultLen; pCur != pEnd; ++pCur)
263 *pCur = 0;
264
265 // perform standard long multiplication
266 const tU32 *pLargeBeg = pLarge->m_blocks;
267 const tU32 *pLargeEnd = pLargeBeg + pLarge->m_length;
268
269 // for each small block
270 tU32 *pResultStart = pResult->m_blocks;
271 for(const tU32 *pSmallCur = pSmall->m_blocks, *pSmallEnd = pSmallCur + pSmall->m_length;
272 pSmallCur != pSmallEnd;
273 ++pSmallCur, ++pResultStart)
274 {
275 // if non-zero, multiply against all the large blocks and add into the result
276 const tU32 multiplier = *pSmallCur;
277 if (multiplier != 0)
278 {
279 const tU32 *pLargeCur = pLargeBeg;
280 tU32 *pResultCur = pResultStart;
281 tU64 carry = 0;
282 do
283 {
284 tU64 product = (*pResultCur) + (*pLargeCur)*(tU64)multiplier + carry;
285 carry = product >> 32;
286 *pResultCur = product & 0xFFFFFFFF;
287 ++pLargeCur;
288 ++pResultCur;
289 } while(pLargeCur != pLargeEnd);
290
291 RJ_ASSERT(pResultCur < pResult->m_blocks + maxResultLen);
292 *pResultCur = (tU32)(carry & 0xFFFFFFFF);
293 }
294 }
295
296 // check if the terminating block has no set bits
297 if (maxResultLen > 0 && pResult->m_blocks[maxResultLen - 1] == 0)
298 pResult->m_length = maxResultLen-1;
299 else
300 pResult->m_length = maxResultLen;
301}
302
303//******************************************************************************
304// result = lhs * rhs
305//******************************************************************************
306static void BigInt_Multiply(tBigInt * pResult, const tBigInt & lhs, tU32 rhs)
307{
308 // perform long multiplication
309 tU32 carry = 0;
310 tU32 *pResultCur = pResult->m_blocks;
311 const tU32 *pLhsCur = lhs.m_blocks;
312 const tU32 *pLhsEnd = lhs.m_blocks + lhs.m_length;
313 for ( ; pLhsCur != pLhsEnd; ++pLhsCur, ++pResultCur )
314 {
315 tU64 product = (tU64)(*pLhsCur) * rhs + carry;
316 *pResultCur = (tU32)(product & 0xFFFFFFFF);
317 carry = product >> 32;
318 }
319
320 // if there is a remaining carry, grow the array
321 if (carry != 0)
322 {
323 // grow the array
324 RJ_ASSERT(lhs.m_length + 1 <= c_BigInt_MaxBlocks);
325 *pResultCur = (tU32)carry;
326 pResult->m_length = lhs.m_length + 1;
327 }
328 else
329 {
330 pResult->m_length = lhs.m_length;
331 }
332}
333
334//******************************************************************************
335// result = in * 2
336//******************************************************************************
337static void BigInt_Multiply2(tBigInt * pResult, const tBigInt &in)
338{
339 // shift all the blocks by one
340 tU32 carry = 0;
341
342 tU32 *pResultCur = pResult->m_blocks;
343 const tU32 *pLhsCur = in.m_blocks;
344 const tU32 *pLhsEnd = in.m_blocks + in.m_length;
345 for ( ; pLhsCur != pLhsEnd; ++pLhsCur, ++pResultCur )
346 {
347 tU32 cur = *pLhsCur;
348 *pResultCur = (cur << 1) | carry;
349 carry = cur >> 31;
350 }
351
352 if (carry != 0)
353 {
354 // grow the array
355 RJ_ASSERT(in.m_length + 1 <= c_BigInt_MaxBlocks);
356 *pResultCur = carry;
357 pResult->m_length = in.m_length + 1;
358 }
359 else
360 {
361 pResult->m_length = in.m_length;
362 }
363}
364
365//******************************************************************************
366// result = result * 2
367//******************************************************************************
368static void BigInt_Multiply2(tBigInt * pResult)
369{
370 // shift all the blocks by one
371 tU32 carry = 0;
372
373 tU32 *pCur = pResult->m_blocks;
374 tU32 *pEnd = pResult->m_blocks + pResult->m_length;
375 for ( ; pCur != pEnd; ++pCur )
376 {
377 tU32 cur = *pCur;
378 *pCur = (cur << 1) | carry;
379 carry = cur >> 31;
380 }
381
382 if (carry != 0)
383 {
384 // grow the array
385 RJ_ASSERT(pResult->m_length + 1 <= c_BigInt_MaxBlocks);
386 *pCur = carry;
387 ++pResult->m_length;
388 }
389}
390
391//******************************************************************************
392// result = result * 10
393//******************************************************************************
394static void BigInt_Multiply10(tBigInt * pResult)
395{
396 // multiply all the blocks
397 tU64 carry = 0;
398
399 tU32 *pCur = pResult->m_blocks;
400 tU32 *pEnd = pResult->m_blocks + pResult->m_length;
401 for ( ; pCur != pEnd; ++pCur )
402 {
403 tU64 product = (tU64)(*pCur) * 10ull + carry;
404 (*pCur) = (tU32)(product & 0xFFFFFFFF);
405 carry = product >> 32;
406 }
407
408 if (carry != 0)
409 {
410 // grow the array
411 RJ_ASSERT(pResult->m_length + 1 <= c_BigInt_MaxBlocks);
412 *pCur = (tU32)carry;
413 ++pResult->m_length;
414 }
415}
416
417//******************************************************************************
418//******************************************************************************
419static tU32 g_PowerOf10_U32[] =
420{
421 1, // 10 ^ 0
422 10, // 10 ^ 1
423 100, // 10 ^ 2
424 1000, // 10 ^ 3
425 10000, // 10 ^ 4
426 100000, // 10 ^ 5
427 1000000, // 10 ^ 6
428 10000000, // 10 ^ 7
429};
430
431//******************************************************************************
432// Note: This has a lot of wasted space in the big integer structures of the
433// early table entries. It wouldn't be terribly hard to make the multiply
434// function work on integer pointers with an array length instead of
435// the tBigInt struct which would allow us to store a minimal amount of
436// data here.
437//******************************************************************************
438static tBigInt g_PowerOf10_Big[] =
439{
440 // 10 ^ 8
441 { 1, { 100000000 } },
442 // 10 ^ 16
443 { 2, { 0x6fc10000, 0x002386f2 } },
444 // 10 ^ 32
445 { 4, { 0x00000000, 0x85acef81, 0x2d6d415b, 0x000004ee, } },
446 // 10 ^ 64
447 { 7, { 0x00000000, 0x00000000, 0xbf6a1f01, 0x6e38ed64, 0xdaa797ed, 0xe93ff9f4, 0x00184f03, } },
448 // 10 ^ 128
449 { 14, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x2e953e01, 0x03df9909, 0x0f1538fd,
450 0x2374e42f, 0xd3cff5ec, 0xc404dc08, 0xbccdb0da, 0xa6337f19, 0xe91f2603, 0x0000024e,
451 }
452 },
453 // 10 ^ 256
454 { 27, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
455 0x00000000, 0x982e7c01, 0xbed3875b, 0xd8d99f72, 0x12152f87, 0x6bde50c6, 0xcf4a6e70,
456 0xd595d80f, 0x26b2716e, 0xadc666b0, 0x1d153624, 0x3c42d35a, 0x63ff540e, 0xcc5573c0,
457 0x65f9ef17, 0x55bc28f2, 0x80dcc7f7, 0xf46eeddc, 0x5fdcefce, 0x000553f7,
458 }
459 }
460};
461
462//******************************************************************************
463// result = 10^exponent
464//******************************************************************************
465static void BigInt_Pow10(tBigInt * pResult, tU32 exponent)
466{
467 // make sure the exponent is within the bounds of the lookup table data
468 RJ_ASSERT(exponent < 512);
469
470 // create two temporary values to reduce large integer copy operations
471 tBigInt temp1;
472 tBigInt temp2;
473 tBigInt *pCurTemp = &temp1;
474 tBigInt *pNextTemp = &temp2;
475
476 // initialize the result by looking up a 32-bit power of 10 corresponding to the first 3 bits
477 tU32 smallExponent = exponent & 0x7;
478 pCurTemp->SetU32(g_PowerOf10_U32[smallExponent]);
479
480 // remove the low bits that we used for the 32-bit lookup table
481 exponent >>= 3;
482 tU32 tableIdx = 0;
483
484 // while there are remaining bits in the exponent to be processed
485 while (exponent != 0)
486 {
487 // if the current bit is set, multiply it with the corresponding power of 10
488 if(exponent & 1)
489 {
490 // multiply into the next temporary
491 BigInt_Multiply( pNextTemp, *pCurTemp, g_PowerOf10_Big[tableIdx] );
492
493 // swap to the next temporary
494 tBigInt * pSwap = pCurTemp;
495 pCurTemp = pNextTemp;
496 pNextTemp = pSwap;
497 }
498
499 // advance to the next bit
500 ++tableIdx;
501 exponent >>= 1;
502 }
503
504 // output the result
505 *pResult = *pCurTemp;
506}
507
508//******************************************************************************
509// result = in * 10^exponent
510//******************************************************************************
511static void BigInt_MultiplyPow10(tBigInt * pResult, const tBigInt & in, tU32 exponent)
512{
513 // make sure the exponent is within the bounds of the lookup table data
514 RJ_ASSERT(exponent < 512);
515
516 // create two temporary values to reduce large integer copy operations
517 tBigInt temp1;
518 tBigInt temp2;
519 tBigInt *pCurTemp = &temp1;
520 tBigInt *pNextTemp = &temp2;
521
522 // initialize the result by looking up a 32-bit power of 10 corresponding to the first 3 bits
523 tU32 smallExponent = exponent & 0x7;
524 if (smallExponent != 0)
525 {
526 BigInt_Multiply( pCurTemp, in, g_PowerOf10_U32[smallExponent] );
527 }
528 else
529 {
530 *pCurTemp = in;
531 }
532
533 // remove the low bits that we used for the 32-bit lookup table
534 exponent >>= 3;
535 tU32 tableIdx = 0;
536
537 // while there are remaining bits in the exponent to be processed
538 while (exponent != 0)
539 {
540 // if the current bit is set, multiply it with the corresponding power of 10
541 if(exponent & 1)
542 {
543 // multiply into the next temporary
544 BigInt_Multiply( pNextTemp, *pCurTemp, g_PowerOf10_Big[tableIdx] );
545
546 // swap to the next temporary
547 tBigInt * pSwap = pCurTemp;
548 pCurTemp = pNextTemp;
549 pNextTemp = pSwap;
550 }
551
552 // advance to the next bit
553 ++tableIdx;
554 exponent >>= 1;
555 }
556
557 // output the result
558 *pResult = *pCurTemp;
559}
560
561//******************************************************************************
562// result = 2^exponent
563//******************************************************************************
564static inline void BigInt_Pow2(tBigInt * pResult, tU32 exponent)
565{
566 tU32 blockIdx = exponent / 32;
567 RJ_ASSERT( blockIdx < c_BigInt_MaxBlocks );
568
569 for ( tU32 i = 0; i <= blockIdx; ++i)
570 pResult->m_blocks[i] = 0;
571
572 pResult->m_length = blockIdx + 1;
573
574 tU32 bitIdx = (exponent % 32);
575 pResult->m_blocks[blockIdx] |= (1 << bitIdx);
576}
577
578//******************************************************************************
579// This function will divide two large numbers under the assumption that the
580// result is within the range [0,10) and the input numbers have been shifted
581// to satisfy:
582// - The highest block of the divisor is greater than or equal to 8 such that
583// there is enough precision to make an accurate first guess at the quotient.
584// - The highest block of the divisor is less than the maximum value on an
585// unsigned 32-bit integer such that we can safely increment without overflow.
586// - The dividend does not contain more blocks than the divisor such that we
587// can estimate the quotient by dividing the equivalently placed high blocks.
588//
589// quotient = floor(dividend / divisor)
590// remainder = dividend - quotient*divisor
591//
592// pDividend is updated to be the remainder and the quotient is returned.
593//******************************************************************************
594static tU32 BigInt_DivideWithRemainder_MaxQuotient9(tBigInt * pDividend, const tBigInt & divisor)
595{
596 // Check that the divisor has been correctly shifted into range and that it is not
597 // smaller than the dividend in length.
598 RJ_ASSERT( !divisor.IsZero() &&
599 divisor.m_blocks[divisor.m_length-1] >= 8 &&
600 divisor.m_blocks[divisor.m_length-1] < 0xFFFFFFFF &&
601 pDividend->m_length <= divisor.m_length );
602
603 // If the dividend is smaller than the divisor, the quotient is zero and the divisor is already
604 // the remainder.
605 tU32 length = divisor.m_length;
606 if (pDividend->m_length < divisor.m_length)
607 return 0;
608
609 const tU32 * pFinalDivisorBlock = divisor.m_blocks + length - 1;
610 tU32 * pFinalDividendBlock = pDividend->m_blocks + length - 1;
611
612 // Compute an estimated quotient based on the high block value. This will either match the actual quotient or
613 // undershoot by one.
614 tU32 quotient = *pFinalDividendBlock / (*pFinalDivisorBlock + 1);
615 RJ_ASSERT(quotient <= 9);
616
617 // Divide out the estimated quotient
618 if (quotient != 0)
619 {
620 // dividend = dividend - divisor*quotient
621 const tU32 *pDivisorCur = divisor.m_blocks;
622 tU32 *pDividendCur = pDividend->m_blocks;
623
624 tU64 borrow = 0;
625 tU64 carry = 0;
626 do
627 {
628 tU64 product = (tU64)*pDivisorCur * (tU64)quotient + carry;
629 carry = product >> 32;
630
631 tU64 difference = (tU64)*pDividendCur - (product & 0xFFFFFFFF) - borrow;
632 borrow = (difference >> 32) & 1;
633
634 *pDividendCur = difference & 0xFFFFFFFF;
635
636 ++pDivisorCur;
637 ++pDividendCur;
638 } while(pDivisorCur <= pFinalDivisorBlock);
639
640 // remove all leading zero blocks from dividend
641 while (length > 0 && pDividend->m_blocks[length - 1] == 0)
642 --length;
643
644 pDividend->m_length = length;
645 }
646
647 // If the dividend is still larger than the divisor, we overshot our estimate quotient. To correct,
648 // we increment the quotient and subtract one more divisor from the dividend.
649 if ( BigInt_Compare(*pDividend, divisor) >= 0 )
650 {
651 ++quotient;
652
653 // dividend = dividend - divisor
654 const tU32 *pDivisorCur = divisor.m_blocks;
655 tU32 *pDividendCur = pDividend->m_blocks;
656
657 tU64 borrow = 0;
658 do
659 {
660 tU64 difference = (tU64)*pDividendCur - (tU64)*pDivisorCur - borrow;
661 borrow = (difference >> 32) & 1;
662
663 *pDividendCur = difference & 0xFFFFFFFF;
664
665 ++pDivisorCur;
666 ++pDividendCur;
667 } while(pDivisorCur <= pFinalDivisorBlock);
668
669 // remove all leading zero blocks from dividend
670 while (length > 0 && pDividend->m_blocks[length - 1] == 0)
671 --length;
672
673 pDividend->m_length = length;
674 }
675
676 return quotient;
677}
678
679//******************************************************************************
680// result = result << shift
681//******************************************************************************
682static void BigInt_ShiftLeft(tBigInt * pResult, tU32 shift)
683{
684 RJ_ASSERT( shift != 0 );
685
686 tU32 shiftBlocks = shift / 32;
687 tU32 shiftBits = shift % 32;
688
689 // process blocks high to low so that we can safely process in place
690 const tU32 * pInBlocks = pResult->m_blocks;
691 tS32 inLength = pResult->m_length;
692 RJ_ASSERT( inLength + shiftBlocks < c_BigInt_MaxBlocks );
693
694 // check if the shift is block aligned
695 if (shiftBits == 0)
21
Assuming 'shiftBits' is equal to 0
22
Taking true branch
696 {
697 // copy blcoks from high to low
698 for (tU32 * pInCur = pResult->m_blocks + inLength, *pOutCur = pInCur + shiftBlocks;
23
Loop condition is true. Entering loop body
699 pInCur >= pInBlocks;
700 --pInCur, --pOutCur)
701 {
702 *pOutCur = *pInCur;
24
Assigned value is garbage or undefined
703 }
704
705 // zero the remaining low blocks
706 for ( tU32 i = 0; i < shiftBlocks; ++i)
707 pResult->m_blocks[i] = 0;
708
709 pResult->m_length += shiftBlocks;
710 }
711 // else we need to shift partial blocks
712 else
713 {
714 tS32 inBlockIdx = inLength - 1;
715 tU32 outBlockIdx = inLength + shiftBlocks;
716
717 // set the length to hold the shifted blocks
718 RJ_ASSERT( outBlockIdx < c_BigInt_MaxBlocks );
719 pResult->m_length = outBlockIdx + 1;
720
721 // output the initial blocks
722 const tU32 lowBitsShift = (32 - shiftBits);
723 tU32 highBits = 0;
724 tU32 block = pResult->m_blocks[inBlockIdx];
725 tU32 lowBits = block >> lowBitsShift;
726 while ( inBlockIdx > 0 )
727 {
728 pResult->m_blocks[outBlockIdx] = highBits | lowBits;
729 highBits = block << shiftBits;
730
731 --inBlockIdx;
732 --outBlockIdx;
733
734 block = pResult->m_blocks[inBlockIdx];
735 lowBits = block >> lowBitsShift;
736 }
737
738 // output the final blocks
739 RJ_ASSERT( outBlockIdx == shiftBlocks + 1 );
740 pResult->m_blocks[outBlockIdx] = highBits | lowBits;
741 pResult->m_blocks[outBlockIdx-1] = block << shiftBits;
742
743 // zero the remaining low blocks
744 for ( tU32 i = 0; i < shiftBlocks; ++i)
745 pResult->m_blocks[i] = 0;
746
747 // check if the terminating block has no set bits
748 if (pResult->m_blocks[pResult->m_length - 1] == 0)
749 --pResult->m_length;
750 }
751}
752
753//******************************************************************************
754// This is an implementation the Dragon4 algorithm to convert a binary number
755// in floating point format to a decimal number in string format. The function
756// returns the number of digits written to the output buffer and the output is
757// not NUL terminated.
758//
759// The floating point input value is (mantissa * 2^exponent).
760//
761// See the following papers for more information on the algorithm:
762// "How to Print Floating-Point Numbers Accurately"
763// Steele and White
764// http://kurtstephens.com/files/p372-steele.pdf
765// "Printing Floating-Point Numbers Quickly and Accurately"
766// Burger and Dybvig
767// http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.4656&rep=rep1&type=pdf
768//******************************************************************************
769tU32 Dragon4
770(
771 const tU64 mantissa, // value significand
772 const tS32 exponent, // value exponent in base 2
773 const tU32 mantissaHighBitIdx, // index of the highest set mantissa bit
774 const tB hasUnequalMargins, // is the high margin twice as large as the low margin
775 const tCutoffMode cutoffMode, // how to determine output length
776 tU32 cutoffNumber, // parameter to the selected cutoffMode
777 tC8 * pOutBuffer, // buffer to output into
778 tU32 bufferSize, // maximum characters that can be printed to pOutBuffer
779 tS32 * pOutExponent // the base 10 exponent of the first digit
780)
781{
782 tC8 * pCurDigit = pOutBuffer;
783
784 RJ_ASSERT( bufferSize > 0 );
785
786 // if the mantissa is zero, the value is zero regardless of the exponent
787 if (mantissa == 0)
1
Assuming 'mantissa' is not equal to 0
2
Taking false branch
788 {
789 *pCurDigit = '0';
790 *pOutExponent = 0;
791 return 1;
792 }
793
794 // compute the initial state in integral form such that
795 // value = scaledValue / scale
796 // marginLow = scaledMarginLow / scale
797 tBigInt scale; // positive scale applied to value and margin such that they can be
798 // represented as whole numbers
799 tBigInt scaledValue; // scale * mantissa
800 tBigInt scaledMarginLow; // scale * 0.5 * (distance between this floating-point number and its
801 // immediate lower value)
802
803 // For normalized IEEE floating point values, each time the exponent is incremented the margin also
804 // doubles. That creates a subset of transition numbers where the high margin is twice the size of
805 // the low margin.
806 tBigInt * pScaledMarginHigh;
807 tBigInt optionalMarginHigh;
808
809 if ( hasUnequalMargins )
3
Assuming 'hasUnequalMargins' is 0
4
Taking false branch
810 {
811 // if we have no fractional component
812 if (exponent > 0)
813 {
814 // 1) Expand the input value by multiplying out the mantissa and exponent. This represents
815 // the input value in its whole number representation.
816 // 2) Apply an additional scale of 2 such that later comparisons against the margin values
817 // are simplified.
818 // 3) Set the margin value to the lowest mantissa bit's scale.
819
820 // scaledValue = 2 * 2 * mantissa*2^exponent
821 scaledValue.SetU64( 4 * mantissa );
822 BigInt_ShiftLeft( &scaledValue, exponent );
823
824 // scale = 2 * 2 * 1
825 scale.SetU32( 4 );
826
827 // scaledMarginLow = 2 * 2^(exponent-1)
828 BigInt_Pow2( &scaledMarginLow, exponent );
829
830 // scaledMarginHigh = 2 * 2 * 2^(exponent-1)
831 BigInt_Pow2( &optionalMarginHigh, exponent + 1 );
832 }
833 // else we have a fractional exponent
834 else
835 {
836 // In order to track the mantissa data as an integer, we store it as is with a large scale
837
838 // scaledValue = 2 * 2 * mantissa
839 scaledValue.SetU64( 4 * mantissa );
840
841 // scale = 2 * 2 * 2^(-exponent)
842 BigInt_Pow2(&scale, -exponent + 2 );
843
844 // scaledMarginLow = 2 * 2^(-1)
845 scaledMarginLow.SetU32( 1 );
846
847 // scaledMarginHigh = 2 * 2 * 2^(-1)
848 optionalMarginHigh.SetU32( 2 );
849 }
850
851 // the high and low margins are different
852 pScaledMarginHigh = &optionalMarginHigh;
853 }
854 else
855 {
856 // if we have no fractional component
857 if (exponent > 0)
5
Assuming 'exponent' is <= 0
6
Taking false branch
858 {
859 // 1) Expand the input value by multiplying out the mantissa and exponent. This represents
860 // the input value in its whole number representation.
861 // 2) Apply an additional scale of 2 such that later comparisons against the margin values
862 // are simplified.
863 // 3) Set the margin value to the lowest mantissa bit's scale.
864
865 // scaledValue = 2 * mantissa*2^exponent
866 scaledValue.SetU64( 2 * mantissa );
867 BigInt_ShiftLeft( &scaledValue, exponent );
868
869 // scale = 2 * 1
870 scale.SetU32( 2 );
871
872 // scaledMarginLow = 2 * 2^(exponent-1)
873 BigInt_Pow2( &scaledMarginLow, exponent );
874 }
875 // else we have a fractional exponent
876 else
877 {
878 // In order to track the mantissa data as an integer, we store it as is with a large scale
879
880 // scaledValue = 2 * mantissa
881 scaledValue.SetU64( 2 * mantissa );
882
883 // scale = 2 * 2^(-exponent)
884 BigInt_Pow2(&scale, -exponent + 1 );
885
886 // scaledMarginLow = 2 * 2^(-1)
887 scaledMarginLow.SetU32( 1 );
888 }
889
890 // the high and low margins are equal
891 pScaledMarginHigh = &scaledMarginLow;
892 }
893
894 // Compute an estimate for digitExponent that will be correct or undershoot by one.
895 // This optimization is based on the paper "Printing Floating-Point Numbers Quickly and Accurately"
896 // by Burger and Dybvig http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.4656&rep=rep1&type=pdf
897 // We perform an additional subtraction of 0.69 to increase the frequency of a failed estimate
898 // because that lets us take a faster branch in the code. 0.69 is chosen because 0.69 + log10(2) is
899 // less than one by a reasonable epsilon that will account for any floating point error.
900 //
901 // We want to set digitExponent to floor(log10(v)) + 1
902 // v = mantissa*2^exponent
903 // log2(v) = log2(mantissa) + exponent;
904 // log10(v) = log2(v) * log10(2)
905 // floor(log2(v)) = mantissaHighBitIdx + exponent;
906 // log10(v) - log10(2) < (mantissaHighBitIdx + exponent) * log10(2) <= log10(v)
907 // log10(v) < (mantissaHighBitIdx + exponent) * log10(2) + log10(2) <= log10(v) + log10(2)
908 // floor( log10(v) ) < ceil( (mantissaHighBitIdx + exponent) * log10(2) ) <= floor( log10(v) ) + 1
909 const tF64 log10_2 = 0.30102999566398119521373889472449;
910 tS32 digitExponent = (tS32)(ceil(tF64((tS32)mantissaHighBitIdx + exponent) * log10_2 - 0.69));
911
912 // if the digit exponent is smaller than the smallest desired digit for fractional cutoff,
913 // pull the digit back into legal range at which point we will round to the appropriate value.
914 // Note that while our value for digitExponent is still an estimate, this is safe because it
915 // only increases the number. This will either correct digitExponent to an accurate value or it
916 // will clamp it above the accurate value.
917 if (cutoffMode == CutoffMode_FractionLength && digitExponent <= -(tS32)cutoffNumber)
7
Assuming 'cutoffMode' is not equal to CutoffMode_FractionLength
918 {
919 digitExponent = -(tS32)cutoffNumber + 1;
920 }
921
922 // Divide value by 10^digitExponent.
923 if (digitExponent > 0)
8
Assuming 'digitExponent' is <= 0
9
Taking false branch
924 {
925 // The exponent is positive creating a division so we multiply up the scale.
926 tBigInt temp;
927 BigInt_MultiplyPow10( &temp, scale, digitExponent );
928 scale = temp;
929 }
930 else if (digitExponent < 0)
10
Assuming 'digitExponent' is >= 0
11
Taking false branch
931 {
932 // The exponent is negative creating a multiplication so we multiply up the scaledValue,
933 // scaledMarginLow and scaledMarginHigh.
934 tBigInt pow10;
935 BigInt_Pow10( &pow10, -digitExponent);
936
937 tBigInt temp;
938 BigInt_Multiply( &temp, scaledValue, pow10);
939 scaledValue = temp;
940
941 BigInt_Multiply( &temp, scaledMarginLow, pow10);
942 scaledMarginLow = temp;
943
944 if (pScaledMarginHigh != &scaledMarginLow)
945 BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow );
946 }
947
948 // If (value + marginHigh) >= 1, our estimate for digitExponent was too low
949 tBigInt scaledValueHigh;
950 BigInt_Add( &scaledValueHigh, scaledValue, *pScaledMarginHigh );
951 if( BigInt_Compare(scaledValueHigh,scale) >= 0 )
12
Taking false branch
952 {
953 // The exponent estimate was incorrect.
954 // Increment the exponent and don't perform the premultiply needed
955 // for the first loop iteration.
956 digitExponent = digitExponent + 1;
957 }
958 else
959 {
960 // The exponent estimate was correct.
961 // Multiply larger by the output base to prepare for the first loop iteration.
962 BigInt_Multiply10( &scaledValue );
963 BigInt_Multiply10( &scaledMarginLow );
964 if (pScaledMarginHigh != &scaledMarginLow)
13
Taking false branch
965 BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow );
966 }
967
968 // Compute the cutoff exponent (the exponent of the final digit to print).
969 // Default to the maximum size of the output buffer.
970 tS32 cutoffExponent = digitExponent - bufferSize;
971 switch(cutoffMode)
14
Control jumps to 'case CutoffMode_TotalLength:' at line 978
972 {
973 // print digits until we pass the accuracy margin limits or buffer size
974 case CutoffMode_Unique:
975 break;
976
977 // print cutoffNumber of digits or until we reach the buffer size
978 case CutoffMode_TotalLength:
979 {
980 tS32 desiredCutoffExponent = digitExponent - (tS32)cutoffNumber;
981 if (desiredCutoffExponent > cutoffExponent)
15
Taking false branch
982 cutoffExponent = desiredCutoffExponent;
983 }
984 break;
16
Execution continues on line 997
985
986 // print cutoffNumber digits past the decimal point or until we reach the buffer size
987 case CutoffMode_FractionLength:
988 {
989 tS32 desiredCutoffExponent = -(tS32)cutoffNumber;
990 if (desiredCutoffExponent > cutoffExponent)
991 cutoffExponent = desiredCutoffExponent;
992 }
993 break;
994 }
995
996 // Output the exponent of the first digit we will print
997 *pOutExponent = digitExponent-1;
998
999 // In preparation for calling BigInt_DivideWithRemainder_MaxQuotient9(),
1000 // we need to scale up our values such that the highest block of the denominator
1001 // is greater than or equal to 8. We also need to guarantee that the numerator
1002 // can never have a length greater than the denominator after each loop iteration.
1003 // This requires the highest block of the denominator to be less than or equal to
1004 // 429496729 which is the highest number that can be multiplied by 10 without
1005 // overflowing to a new block.
1006 RJ_ASSERT( scale.GetLength() > 0 );
1007 tU32 hiBlock = scale.GetBlock( scale.GetLength() - 1 );
1008 if (hiBlock < 8 || hiBlock > 429496729)
17
Assuming 'hiBlock' is >= 8
18
Assuming 'hiBlock' is > 429496729
19
Taking true branch
1009 {
1010 // Perform a bit shift on all values to get the highest block of the denominator into
1011 // the range [8,429496729]. We are more likely to make accurate quotient estimations
1012 // in BigInt_DivideWithRemainder_MaxQuotient9() with higher denominator values so
1013 // we shift the denominator to place the highest bit at index 27 of the highest block.
1014 // This is safe because (2^28 - 1) = 268435455 which is less than 429496729. This means
1015 // that all values with a highest bit at index 27 are within range.
1016 tU32 hiBlockLog2 = LogBase2(hiBlock);
1017 RJ_ASSERT(hiBlockLog2 < 3 || hiBlockLog2 > 27);
1018 tU32 shift = (32 + 27 - hiBlockLog2) % 32;
1019
1020 BigInt_ShiftLeft( &scale, shift );
20
Calling 'BigInt_ShiftLeft'
1021 BigInt_ShiftLeft( &scaledValue, shift);
1022 BigInt_ShiftLeft( &scaledMarginLow, shift);
1023 if (pScaledMarginHigh != &scaledMarginLow)
1024 BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow );
1025 }
1026
1027 // These values are used to inspect why the print loop terminated so we can properly
1028 // round the final digit.
1029 tB low; // did the value get within marginLow distance from zero
1030 tB high; // did the value get within marginHigh distance from one
1031 tU32 outputDigit; // current digit being output
1032
1033 if (cutoffMode == CutoffMode_Unique)
1034 {
1035 // For the unique cutoff mode, we will try to print until we have reached a level of
1036 // precision that uniquely distinguishes this value from its neighbors. If we run
1037 // out of space in the output buffer, we terminate early.
1038 for (;;)
1039 {
1040 digitExponent = digitExponent-1;
1041
1042 // divide out the scale to extract the digit
1043 outputDigit = BigInt_DivideWithRemainder_MaxQuotient9(&scaledValue, scale);
1044 RJ_ASSERT( outputDigit < 10 );
1045
1046 // update the high end of the value
1047 BigInt_Add( &scaledValueHigh, scaledValue, *pScaledMarginHigh );
1048
1049 // stop looping if we are far enough away from our neighboring values
1050 // or if we have reached the cutoff digit
1051 low = BigInt_Compare(scaledValue, scaledMarginLow) < 0;
1052 high = BigInt_Compare(scaledValueHigh, scale) > 0;
1053 if (low | high | (digitExponent == cutoffExponent))
1054 break;
1055
1056 // store the output digit
1057 *pCurDigit = (tC8)('0' + outputDigit);
1058 ++pCurDigit;
1059
1060 // multiply larger by the output base
1061 BigInt_Multiply10( &scaledValue );
1062 BigInt_Multiply10( &scaledMarginLow );
1063 if (pScaledMarginHigh != &scaledMarginLow)
1064 BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow );
1065 }
1066 }
1067 else
1068 {
1069 // For length based cutoff modes, we will try to print until we
1070 // have exhausted all precision (i.e. all remaining digits are zeros) or
1071 // until we reach the desired cutoff digit.
1072 low = false;
1073 high = false;
1074
1075 for (;;)
1076 {
1077 digitExponent = digitExponent-1;
1078
1079 // divide out the scale to extract the digit
1080 outputDigit = BigInt_DivideWithRemainder_MaxQuotient9(&scaledValue, scale);
1081 RJ_ASSERT( outputDigit < 10 );
1082
1083 if ( scaledValue.IsZero() | (digitExponent == cutoffExponent) )
1084 break;
1085
1086 // store the output digit
1087 *pCurDigit = (tC8)('0' + outputDigit);
1088 ++pCurDigit;
1089
1090 // multiply larger by the output base
1091 BigInt_Multiply10(&scaledValue);
1092 }
1093 }
1094
1095 // round off the final digit
1096 // default to rounding down if value got too close to 0
1097 tB roundDown = low;
1098
1099 // if it is legal to round up and down
1100 if (low == high)
1101 {
1102 // round to the closest digit by comparing value with 0.5. To do this we need to convert
1103 // the inequality to large integer values.
1104 // compare( value, 0.5 )
1105 // compare( scale * value, scale * 0.5 )
1106 // compare( 2 * scale * value, scale )
1107 BigInt_Multiply2(&scaledValue);
1108 tS32 compare = BigInt_Compare(scaledValue, scale);
1109 roundDown = compare < 0;
1110
1111 // if we are directly in the middle, round towards the even digit (i.e. IEEE rouding rules)
1112 if (compare == 0)
1113 roundDown = (outputDigit & 1) == 0;
1114 }
1115
1116 // print the rounded digit
1117 if (roundDown)
1118 {
1119 *pCurDigit = (tC8)('0' + outputDigit);
1120 ++pCurDigit;
1121 }
1122 else
1123 {
1124 // handle rounding up
1125 if (outputDigit == 9)
1126 {
1127 // find the first non-nine prior digit
1128 for (;;)
1129 {
1130 // if we are at the first digit
1131 if (pCurDigit == pOutBuffer)
1132 {
1133 // output 1 at the next highest exponent
1134 *pCurDigit = '1';
1135 ++pCurDigit;
1136 *pOutExponent += 1;
1137 break;
1138 }
1139
1140 --pCurDigit;
1141 if (*pCurDigit != '9')
1142 {
1143 // increment the digit
1144 *pCurDigit += 1;
1145 ++pCurDigit;
1146 break;
1147 }
1148 }
1149 }
1150 else
1151 {
1152 // values in the range [0,8] can perform a simple round up
1153 *pCurDigit = (tC8)('0' + outputDigit + 1);
1154 ++pCurDigit;
1155 }
1156 }
1157
1158 // return the number of digits output
1159 RJ_ASSERT(pCurDigit - pOutBuffer <= (tPtrDiff)bufferSize);
1160 return pCurDigit - pOutBuffer;
1161}
diff --git a/scan-build/report-b77ae8.html b/scan-build/report-b77ae8.html deleted file mode 100644 index 9fc43178..00000000 --- a/scan-build/report-b77ae8.html +++ /dev/null @@ -1,1288 +0,0 @@ - - - -lib/dconv/dragon4.cpp - - - - - - - - - - - - - - - - - - - - - - - - - -

Bug Summary

- - - - -
File:dconv/dragon4.cpp
Location:line 660, column 51
Description:The left operand of '-' is a garbage value
- -

Annotated Source Code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/******************************************************************************
2 Copyright (c) 2014 Ryan Juckett
3 http://www.ryanjuckett.com/
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17
18 2. Altered source versions must be plainly marked as such, and must not be
19 misrepresented as being the original software.
20
21 3. This notice may not be removed or altered from any source
22 distribution.
23*******************************************************************************
24 Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
25 All rights reserved.
26
27 Redistribution and use in source and binary forms, with or without
28 modification, are permitted provided that the following conditions
29 are met:
30 1. Redistributions of source code must retain the above copyright
31 notice, this list of conditions and the following disclaimer.
32
33 2. Redistributions in binary form must reproduce the above copyright
34 notice, this list of conditions and the following disclaimer in the
35 documentation and/or other materials provided with the distribution.
36
37 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
38 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
40 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
41 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
46 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47
48 The origin source code can be obtained from:
49 http://www.ryanjuckett.com/
50
51******************************************************************************/
52
53#include "math.h"
54#include "dmath.h"
55#include "dragon4.h"
56
57//******************************************************************************
58// Maximum number of 32 bit blocks needed in high precision arithmetic
59// to print out 64 bit IEEE floating point values.
60//******************************************************************************
61const tU32 c_BigInt_MaxBlocks = 35;
62
63//******************************************************************************
64// This structure stores a high precision unsigned integer. It uses a buffer
65// of 32 bit integer blocks along with a length. The lowest bits of the integer
66// are stored at the start of the buffer and the length is set to the minimum
67// value that contains the integer. Thus, there are never any zero blocks at the
68// end of the buffer.
69//******************************************************************************
70struct tBigInt
71{
72 // Copy integer
73 tBigInt & operator=(const tBigInt &rhs)
74 {
75 tU32 length = rhs.m_length;
76 tU32 * pLhsCur = m_blocks;
77 for (const tU32 *pRhsCur = rhs.m_blocks, *pRhsEnd = pRhsCur + length;
78 pRhsCur != pRhsEnd;
79 ++pLhsCur, ++pRhsCur)
80 {
81 *pLhsCur = *pRhsCur;
82 }
83 m_length = length;
84 return *this;
85 }
86
87 // Data accessors
88 tU32 GetLength() const {
89 return m_length;
90 }
91 tU32 GetBlock(tU32 idx) const {
92 return m_blocks[idx];
93 }
94
95 // Zero helper functions
96 void SetZero() {
97 m_length = 0;
98 }
99 tB IsZero() const {
100 return m_length == 0;
101 }
102
103 // Basic type accessors
104 void SetU64(tU64 val)
105 {
106 if (val > 0xFFFFFFFF)
107 {
108 m_blocks[0] = val & 0xFFFFFFFF;
109 m_blocks[1] = (val >> 32) & 0xFFFFFFFF;
110 m_length = 2;
111 }
112 else if (val != 0)
113 {
114 m_blocks[0] = val & 0xFFFFFFFF;
115 m_length = 1;
116 }
117 else
118 {
119 m_length = 0;
120 }
121 }
122
123 void SetU32(tU32 val)
124 {
125 if (val != 0)
126 {
127 m_blocks[0] = val;
128 m_length = (val != 0);
129 }
130 else
131 {
132 m_length = 0;
133 }
134 }
135
136 tU32 GetU32() const {
137 return (m_length == 0) ? 0 : m_blocks[0];
138 }
139
140 // Member data
141 tU32 m_length;
142 tU32 m_blocks[c_BigInt_MaxBlocks];
143};
144
145//******************************************************************************
146// Returns 0 if (lhs = rhs), negative if (lhs < rhs), positive if (lhs > rhs)
147//******************************************************************************
148static tS32 BigInt_Compare(const tBigInt & lhs, const tBigInt & rhs)
149{
150 // A bigger length implies a bigger number.
151 tS32 lengthDiff = lhs.m_length - rhs.m_length;
152 if (lengthDiff != 0)
153 return lengthDiff;
154
155 // Compare blocks one by one from high to low.
156 for (tS32 i = lhs.m_length - 1; i >= 0; --i)
157 {
158 if (lhs.m_blocks[i] == rhs.m_blocks[i])
159 continue;
160 else if (lhs.m_blocks[i] > rhs.m_blocks[i])
161 return 1;
162 else
163 return -1;
164 }
165
166 // no blocks differed
167 return 0;
168}
169
170//******************************************************************************
171// result = lhs + rhs
172//******************************************************************************
173static void BigInt_Add(tBigInt * pResult, const tBigInt & lhs, const tBigInt & rhs)
174{
175 // determine which operand has the smaller length
176 const tBigInt * pLarge;
177 const tBigInt * pSmall;
178 if (lhs.m_length < rhs.m_length)
179 {
180 pSmall = &lhs;
181 pLarge = &rhs;
182 }
183 else
184 {
185 pSmall = &rhs;
186 pLarge = &lhs;
187 }
188
189 const tU32 largeLen = pLarge->m_length;
190 const tU32 smallLen = pSmall->m_length;
191
192 // The output will be at least as long as the largest input
193 pResult->m_length = largeLen;
194
195 // Add each block and add carry the overflow to the next block
196 tU64 carry = 0;
197 const tU32 * pLargeCur = pLarge->m_blocks;
198 const tU32 * pLargeEnd = pLargeCur + largeLen;
199 const tU32 * pSmallCur = pSmall->m_blocks;
200 const tU32 * pSmallEnd = pSmallCur + smallLen;
201 tU32 * pResultCur = pResult->m_blocks;
202 while (pSmallCur != pSmallEnd)
203 {
204 tU64 sum = carry + (tU64)(*pLargeCur) + (tU64)(*pSmallCur);
205 carry = sum >> 32;
206 (*pResultCur) = sum & 0xFFFFFFFF;
207 ++pLargeCur;
208 ++pSmallCur;
209 ++pResultCur;
210 }
211
212 // Add the carry to any blocks that only exist in the large operand
213 while (pLargeCur != pLargeEnd)
214 {
215 tU64 sum = carry + (tU64)(*pLargeCur);
216 carry = sum >> 32;
217 (*pResultCur) = sum & 0xFFFFFFFF;
218 ++pLargeCur;
219 ++pResultCur;
220 }
221
222 // If there's still a carry, append a new block
223 if (carry != 0)
224 {
225 RJ_ASSERT(carry == 1);
226 RJ_ASSERT((tU32)(pResultCur - pResult->m_blocks) == largeLen && (largeLen < c_BigInt_MaxBlocks));
227 *pResultCur = 1;
228 pResult->m_length = largeLen + 1;
229 }
230 else
231 {
232 pResult->m_length = largeLen;
233 }
234}
235
236//******************************************************************************
237// result = lhs * rhs
238//******************************************************************************
239static void BigInt_Multiply(tBigInt * pResult, const tBigInt &lhs, const tBigInt &rhs)
240{
241 RJ_ASSERT( pResult != &lhs && pResult != &rhs );
242
243 // determine which operand has the smaller length
244 const tBigInt * pLarge;
245 const tBigInt * pSmall;
246 if (lhs.m_length < rhs.m_length)
247 {
248 pSmall = &lhs;
249 pLarge = &rhs;
250 }
251 else
252 {
253 pSmall = &rhs;
254 pLarge = &lhs;
255 }
256
257 // set the maximum possible result length
258 tU32 maxResultLen = pLarge->m_length + pSmall->m_length;
259 RJ_ASSERT( maxResultLen <= c_BigInt_MaxBlocks );
260
261 // clear the result data
262 for(tU32 * pCur = pResult->m_blocks, *pEnd = pCur + maxResultLen; pCur != pEnd; ++pCur)
263 *pCur = 0;
264
265 // perform standard long multiplication
266 const tU32 *pLargeBeg = pLarge->m_blocks;
267 const tU32 *pLargeEnd = pLargeBeg + pLarge->m_length;
268
269 // for each small block
270 tU32 *pResultStart = pResult->m_blocks;
271 for(const tU32 *pSmallCur = pSmall->m_blocks, *pSmallEnd = pSmallCur + pSmall->m_length;
272 pSmallCur != pSmallEnd;
273 ++pSmallCur, ++pResultStart)
274 {
275 // if non-zero, multiply against all the large blocks and add into the result
276 const tU32 multiplier = *pSmallCur;
277 if (multiplier != 0)
278 {
279 const tU32 *pLargeCur = pLargeBeg;
280 tU32 *pResultCur = pResultStart;
281 tU64 carry = 0;
282 do
283 {
284 tU64 product = (*pResultCur) + (*pLargeCur)*(tU64)multiplier + carry;
285 carry = product >> 32;
286 *pResultCur = product & 0xFFFFFFFF;
287 ++pLargeCur;
288 ++pResultCur;
289 } while(pLargeCur != pLargeEnd);
290
291 RJ_ASSERT(pResultCur < pResult->m_blocks + maxResultLen);
292 *pResultCur = (tU32)(carry & 0xFFFFFFFF);
293 }
294 }
295
296 // check if the terminating block has no set bits
297 if (maxResultLen > 0 && pResult->m_blocks[maxResultLen - 1] == 0)
298 pResult->m_length = maxResultLen-1;
299 else
300 pResult->m_length = maxResultLen;
301}
302
303//******************************************************************************
304// result = lhs * rhs
305//******************************************************************************
306static void BigInt_Multiply(tBigInt * pResult, const tBigInt & lhs, tU32 rhs)
307{
308 // perform long multiplication
309 tU32 carry = 0;
310 tU32 *pResultCur = pResult->m_blocks;
311 const tU32 *pLhsCur = lhs.m_blocks;
312 const tU32 *pLhsEnd = lhs.m_blocks + lhs.m_length;
313 for ( ; pLhsCur != pLhsEnd; ++pLhsCur, ++pResultCur )
314 {
315 tU64 product = (tU64)(*pLhsCur) * rhs + carry;
316 *pResultCur = (tU32)(product & 0xFFFFFFFF);
317 carry = product >> 32;
318 }
319
320 // if there is a remaining carry, grow the array
321 if (carry != 0)
322 {
323 // grow the array
324 RJ_ASSERT(lhs.m_length + 1 <= c_BigInt_MaxBlocks);
325 *pResultCur = (tU32)carry;
326 pResult->m_length = lhs.m_length + 1;
327 }
328 else
329 {
330 pResult->m_length = lhs.m_length;
331 }
332}
333
334//******************************************************************************
335// result = in * 2
336//******************************************************************************
337static void BigInt_Multiply2(tBigInt * pResult, const tBigInt &in)
338{
339 // shift all the blocks by one
340 tU32 carry = 0;
341
342 tU32 *pResultCur = pResult->m_blocks;
343 const tU32 *pLhsCur = in.m_blocks;
344 const tU32 *pLhsEnd = in.m_blocks + in.m_length;
345 for ( ; pLhsCur != pLhsEnd; ++pLhsCur, ++pResultCur )
346 {
347 tU32 cur = *pLhsCur;
348 *pResultCur = (cur << 1) | carry;
349 carry = cur >> 31;
350 }
351
352 if (carry != 0)
353 {
354 // grow the array
355 RJ_ASSERT(in.m_length + 1 <= c_BigInt_MaxBlocks);
356 *pResultCur = carry;
357 pResult->m_length = in.m_length + 1;
358 }
359 else
360 {
361 pResult->m_length = in.m_length;
362 }
363}
364
365//******************************************************************************
366// result = result * 2
367//******************************************************************************
368static void BigInt_Multiply2(tBigInt * pResult)
369{
370 // shift all the blocks by one
371 tU32 carry = 0;
372
373 tU32 *pCur = pResult->m_blocks;
374 tU32 *pEnd = pResult->m_blocks + pResult->m_length;
375 for ( ; pCur != pEnd; ++pCur )
376 {
377 tU32 cur = *pCur;
378 *pCur = (cur << 1) | carry;
379 carry = cur >> 31;
380 }
381
382 if (carry != 0)
383 {
384 // grow the array
385 RJ_ASSERT(pResult->m_length + 1 <= c_BigInt_MaxBlocks);
386 *pCur = carry;
387 ++pResult->m_length;
388 }
389}
390
391//******************************************************************************
392// result = result * 10
393//******************************************************************************
394static void BigInt_Multiply10(tBigInt * pResult)
395{
396 // multiply all the blocks
397 tU64 carry = 0;
398
399 tU32 *pCur = pResult->m_blocks;
400 tU32 *pEnd = pResult->m_blocks + pResult->m_length;
401 for ( ; pCur != pEnd; ++pCur )
14
Loop condition is false. Execution continues on line 408
402 {
403 tU64 product = (tU64)(*pCur) * 10ull + carry;
404 (*pCur) = (tU32)(product & 0xFFFFFFFF);
405 carry = product >> 32;
406 }
407
408 if (carry != 0)
15
Taking false branch
409 {
410 // grow the array
411 RJ_ASSERT(pResult->m_length + 1 <= c_BigInt_MaxBlocks);
412 *pCur = (tU32)carry;
413 ++pResult->m_length;
414 }
415}
416
417//******************************************************************************
418//******************************************************************************
419static tU32 g_PowerOf10_U32[] =
420{
421 1, // 10 ^ 0
422 10, // 10 ^ 1
423 100, // 10 ^ 2
424 1000, // 10 ^ 3
425 10000, // 10 ^ 4
426 100000, // 10 ^ 5
427 1000000, // 10 ^ 6
428 10000000, // 10 ^ 7
429};
430
431//******************************************************************************
432// Note: This has a lot of wasted space in the big integer structures of the
433// early table entries. It wouldn't be terribly hard to make the multiply
434// function work on integer pointers with an array length instead of
435// the tBigInt struct which would allow us to store a minimal amount of
436// data here.
437//******************************************************************************
438static tBigInt g_PowerOf10_Big[] =
439{
440 // 10 ^ 8
441 { 1, { 100000000 } },
442 // 10 ^ 16
443 { 2, { 0x6fc10000, 0x002386f2 } },
444 // 10 ^ 32
445 { 4, { 0x00000000, 0x85acef81, 0x2d6d415b, 0x000004ee, } },
446 // 10 ^ 64
447 { 7, { 0x00000000, 0x00000000, 0xbf6a1f01, 0x6e38ed64, 0xdaa797ed, 0xe93ff9f4, 0x00184f03, } },
448 // 10 ^ 128
449 { 14, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x2e953e01, 0x03df9909, 0x0f1538fd,
450 0x2374e42f, 0xd3cff5ec, 0xc404dc08, 0xbccdb0da, 0xa6337f19, 0xe91f2603, 0x0000024e,
451 }
452 },
453 // 10 ^ 256
454 { 27, { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
455 0x00000000, 0x982e7c01, 0xbed3875b, 0xd8d99f72, 0x12152f87, 0x6bde50c6, 0xcf4a6e70,
456 0xd595d80f, 0x26b2716e, 0xadc666b0, 0x1d153624, 0x3c42d35a, 0x63ff540e, 0xcc5573c0,
457 0x65f9ef17, 0x55bc28f2, 0x80dcc7f7, 0xf46eeddc, 0x5fdcefce, 0x000553f7,
458 }
459 }
460};
461
462//******************************************************************************
463// result = 10^exponent
464//******************************************************************************
465static void BigInt_Pow10(tBigInt * pResult, tU32 exponent)
466{
467 // make sure the exponent is within the bounds of the lookup table data
468 RJ_ASSERT(exponent < 512);
469
470 // create two temporary values to reduce large integer copy operations
471 tBigInt temp1;
472 tBigInt temp2;
473 tBigInt *pCurTemp = &temp1;
474 tBigInt *pNextTemp = &temp2;
475
476 // initialize the result by looking up a 32-bit power of 10 corresponding to the first 3 bits
477 tU32 smallExponent = exponent & 0x7;
478 pCurTemp->SetU32(g_PowerOf10_U32[smallExponent]);
479
480 // remove the low bits that we used for the 32-bit lookup table
481 exponent >>= 3;
482 tU32 tableIdx = 0;
483
484 // while there are remaining bits in the exponent to be processed
485 while (exponent != 0)
486 {
487 // if the current bit is set, multiply it with the corresponding power of 10
488 if(exponent & 1)
489 {
490 // multiply into the next temporary
491 BigInt_Multiply( pNextTemp, *pCurTemp, g_PowerOf10_Big[tableIdx] );
492
493 // swap to the next temporary
494 tBigInt * pSwap = pCurTemp;
495 pCurTemp = pNextTemp;
496 pNextTemp = pSwap;
497 }
498
499 // advance to the next bit
500 ++tableIdx;
501 exponent >>= 1;
502 }
503
504 // output the result
505 *pResult = *pCurTemp;
506}
507
508//******************************************************************************
509// result = in * 10^exponent
510//******************************************************************************
511static void BigInt_MultiplyPow10(tBigInt * pResult, const tBigInt & in, tU32 exponent)
512{
513 // make sure the exponent is within the bounds of the lookup table data
514 RJ_ASSERT(exponent < 512);
515
516 // create two temporary values to reduce large integer copy operations
517 tBigInt temp1;
518 tBigInt temp2;
519 tBigInt *pCurTemp = &temp1;
520 tBigInt *pNextTemp = &temp2;
521
522 // initialize the result by looking up a 32-bit power of 10 corresponding to the first 3 bits
523 tU32 smallExponent = exponent & 0x7;
524 if (smallExponent != 0)
525 {
526 BigInt_Multiply( pCurTemp, in, g_PowerOf10_U32[smallExponent] );
527 }
528 else
529 {
530 *pCurTemp = in;
531 }
532
533 // remove the low bits that we used for the 32-bit lookup table
534 exponent >>= 3;
535 tU32 tableIdx = 0;
536
537 // while there are remaining bits in the exponent to be processed
538 while (exponent != 0)
539 {
540 // if the current bit is set, multiply it with the corresponding power of 10
541 if(exponent & 1)
542 {
543 // multiply into the next temporary
544 BigInt_Multiply( pNextTemp, *pCurTemp, g_PowerOf10_Big[tableIdx] );
545
546 // swap to the next temporary
547 tBigInt * pSwap = pCurTemp;
548 pCurTemp = pNextTemp;
549 pNextTemp = pSwap;
550 }
551
552 // advance to the next bit
553 ++tableIdx;
554 exponent >>= 1;
555 }
556
557 // output the result
558 *pResult = *pCurTemp;
559}
560
561//******************************************************************************
562// result = 2^exponent
563//******************************************************************************
564static inline void BigInt_Pow2(tBigInt * pResult, tU32 exponent)
565{
566 tU32 blockIdx = exponent / 32;
567 RJ_ASSERT( blockIdx < c_BigInt_MaxBlocks );
568
569 for ( tU32 i = 0; i <= blockIdx; ++i)
570 pResult->m_blocks[i] = 0;
571
572 pResult->m_length = blockIdx + 1;
573
574 tU32 bitIdx = (exponent % 32);
575 pResult->m_blocks[blockIdx] |= (1 << bitIdx);
576}
577
578//******************************************************************************
579// This function will divide two large numbers under the assumption that the
580// result is within the range [0,10) and the input numbers have been shifted
581// to satisfy:
582// - The highest block of the divisor is greater than or equal to 8 such that
583// there is enough precision to make an accurate first guess at the quotient.
584// - The highest block of the divisor is less than the maximum value on an
585// unsigned 32-bit integer such that we can safely increment without overflow.
586// - The dividend does not contain more blocks than the divisor such that we
587// can estimate the quotient by dividing the equivalently placed high blocks.
588//
589// quotient = floor(dividend / divisor)
590// remainder = dividend - quotient*divisor
591//
592// pDividend is updated to be the remainder and the quotient is returned.
593//******************************************************************************
594static tU32 BigInt_DivideWithRemainder_MaxQuotient9(tBigInt * pDividend, const tBigInt & divisor)
595{
596 // Check that the divisor has been correctly shifted into range and that it is not
597 // smaller than the dividend in length.
598 RJ_ASSERT( !divisor.IsZero() &&
599 divisor.m_blocks[divisor.m_length-1] >= 8 &&
600 divisor.m_blocks[divisor.m_length-1] < 0xFFFFFFFF &&
601 pDividend->m_length <= divisor.m_length );
602
603 // If the dividend is smaller than the divisor, the quotient is zero and the divisor is already
604 // the remainder.
605 tU32 length = divisor.m_length;
606 if (pDividend->m_length < divisor.m_length)
34
Taking false branch
607 return 0;
608
609 const tU32 * pFinalDivisorBlock = divisor.m_blocks + length - 1;
610 tU32 * pFinalDividendBlock = pDividend->m_blocks + length - 1;
611
612 // Compute an estimated quotient based on the high block value. This will either match the actual quotient or
613 // undershoot by one.
614 tU32 quotient = *pFinalDividendBlock / (*pFinalDivisorBlock + 1);
615 RJ_ASSERT(quotient <= 9);
616
617 // Divide out the estimated quotient
618 if (quotient != 0)
35
Assuming 'quotient' is equal to 0
36
Taking false branch
619 {
620 // dividend = dividend - divisor*quotient
621 const tU32 *pDivisorCur = divisor.m_blocks;
622 tU32 *pDividendCur = pDividend->m_blocks;
623
624 tU64 borrow = 0;
625 tU64 carry = 0;
626 do
627 {
628 tU64 product = (tU64)*pDivisorCur * (tU64)quotient + carry;
629 carry = product >> 32;
630
631 tU64 difference = (tU64)*pDividendCur - (product & 0xFFFFFFFF) - borrow;
632 borrow = (difference >> 32) & 1;
633
634 *pDividendCur = difference & 0xFFFFFFFF;
635
636 ++pDivisorCur;
637 ++pDividendCur;
638 } while(pDivisorCur <= pFinalDivisorBlock);
639
640 // remove all leading zero blocks from dividend
641 while (length > 0 && pDividend->m_blocks[length - 1] == 0)
642 --length;
643
644 pDividend->m_length = length;
645 }
646
647 // If the dividend is still larger than the divisor, we overshot our estimate quotient. To correct,
648 // we increment the quotient and subtract one more divisor from the dividend.
649 if ( BigInt_Compare(*pDividend, divisor) >= 0 )
37
Taking true branch
650 {
651 ++quotient;
652
653 // dividend = dividend - divisor
654 const tU32 *pDivisorCur = divisor.m_blocks;
655 tU32 *pDividendCur = pDividend->m_blocks;
656
657 tU64 borrow = 0;
658 do
38
Loop condition is true. Execution continues on line 660
659 {
660 tU64 difference = (tU64)*pDividendCur - (tU64)*pDivisorCur - borrow;
39
The left operand of '-' is a garbage value
661 borrow = (difference >> 32) & 1;
662
663 *pDividendCur = difference & 0xFFFFFFFF;
664
665 ++pDivisorCur;
666 ++pDividendCur;
667 } while(pDivisorCur <= pFinalDivisorBlock);
668
669 // remove all leading zero blocks from dividend
670 while (length > 0 && pDividend->m_blocks[length - 1] == 0)
671 --length;
672
673 pDividend->m_length = length;
674 }
675
676 return quotient;
677}
678
679//******************************************************************************
680// result = result << shift
681//******************************************************************************
682static void BigInt_ShiftLeft(tBigInt * pResult, tU32 shift)
683{
684 RJ_ASSERT( shift != 0 );
685
686 tU32 shiftBlocks = shift / 32;
687 tU32 shiftBits = shift % 32;
688
689 // process blocks high to low so that we can safely process in place
690 const tU32 * pInBlocks = pResult->m_blocks;
691 tS32 inLength = pResult->m_length;
692 RJ_ASSERT( inLength + shiftBlocks < c_BigInt_MaxBlocks );
693
694 // check if the shift is block aligned
695 if (shiftBits == 0)
25
Taking false branch
696 {
697 // copy blcoks from high to low
698 for (tU32 * pInCur = pResult->m_blocks + inLength, *pOutCur = pInCur + shiftBlocks;
699 pInCur >= pInBlocks;
700 --pInCur, --pOutCur)
701 {
702 *pOutCur = *pInCur;
703 }
704
705 // zero the remaining low blocks
706 for ( tU32 i = 0; i < shiftBlocks; ++i)
707 pResult->m_blocks[i] = 0;
708
709 pResult->m_length += shiftBlocks;
710 }
711 // else we need to shift partial blocks
712 else
713 {
714 tS32 inBlockIdx = inLength - 1;
715 tU32 outBlockIdx = inLength + shiftBlocks;
716
717 // set the length to hold the shifted blocks
718 RJ_ASSERT( outBlockIdx < c_BigInt_MaxBlocks );
719 pResult->m_length = outBlockIdx + 1;
720
721 // output the initial blocks
722 const tU32 lowBitsShift = (32 - shiftBits);
723 tU32 highBits = 0;
724 tU32 block = pResult->m_blocks[inBlockIdx];
725 tU32 lowBits = block >> lowBitsShift;
726 while ( inBlockIdx > 0 )
26
Loop condition is false. Execution continues on line 740
727 {
728 pResult->m_blocks[outBlockIdx] = highBits | lowBits;
729 highBits = block << shiftBits;
730
731 --inBlockIdx;
732 --outBlockIdx;
733
734 block = pResult->m_blocks[inBlockIdx];
735 lowBits = block >> lowBitsShift;
736 }
737
738 // output the final blocks
739 RJ_ASSERT( outBlockIdx == shiftBlocks + 1 );
740 pResult->m_blocks[outBlockIdx] = highBits | lowBits;
741 pResult->m_blocks[outBlockIdx-1] = block << shiftBits;
742
743 // zero the remaining low blocks
744 for ( tU32 i = 0; i < shiftBlocks; ++i)
27
Loop condition is false. Execution continues on line 748
745 pResult->m_blocks[i] = 0;
746
747 // check if the terminating block has no set bits
748 if (pResult->m_blocks[pResult->m_length - 1] == 0)
28
Taking false branch
749 --pResult->m_length;
750 }
751}
752
753//******************************************************************************
754// This is an implementation the Dragon4 algorithm to convert a binary number
755// in floating point format to a decimal number in string format. The function
756// returns the number of digits written to the output buffer and the output is
757// not NUL terminated.
758//
759// The floating point input value is (mantissa * 2^exponent).
760//
761// See the following papers for more information on the algorithm:
762// "How to Print Floating-Point Numbers Accurately"
763// Steele and White
764// http://kurtstephens.com/files/p372-steele.pdf
765// "Printing Floating-Point Numbers Quickly and Accurately"
766// Burger and Dybvig
767// http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.4656&rep=rep1&type=pdf
768//******************************************************************************
769tU32 Dragon4
770(
771 const tU64 mantissa, // value significand
772 const tS32 exponent, // value exponent in base 2
773 const tU32 mantissaHighBitIdx, // index of the highest set mantissa bit
774 const tB hasUnequalMargins, // is the high margin twice as large as the low margin
775 const tCutoffMode cutoffMode, // how to determine output length
776 tU32 cutoffNumber, // parameter to the selected cutoffMode
777 tC8 * pOutBuffer, // buffer to output into
778 tU32 bufferSize, // maximum characters that can be printed to pOutBuffer
779 tS32 * pOutExponent // the base 10 exponent of the first digit
780)
781{
782 tC8 * pCurDigit = pOutBuffer;
783
784 RJ_ASSERT( bufferSize > 0 );
785
786 // if the mantissa is zero, the value is zero regardless of the exponent
787 if (mantissa == 0)
1
Assuming 'mantissa' is not equal to 0
2
Taking false branch
788 {
789 *pCurDigit = '0';
790 *pOutExponent = 0;
791 return 1;
792 }
793
794 // compute the initial state in integral form such that
795 // value = scaledValue / scale
796 // marginLow = scaledMarginLow / scale
797 tBigInt scale; // positive scale applied to value and margin such that they can be
798 // represented as whole numbers
799 tBigInt scaledValue; // scale * mantissa
800 tBigInt scaledMarginLow; // scale * 0.5 * (distance between this floating-point number and its
801 // immediate lower value)
802
803 // For normalized IEEE floating point values, each time the exponent is incremented the margin also
804 // doubles. That creates a subset of transition numbers where the high margin is twice the size of
805 // the low margin.
806 tBigInt * pScaledMarginHigh;
807 tBigInt optionalMarginHigh;
808
809 if ( hasUnequalMargins )
3
Assuming 'hasUnequalMargins' is 0
4
Taking false branch
810 {
811 // if we have no fractional component
812 if (exponent > 0)
813 {
814 // 1) Expand the input value by multiplying out the mantissa and exponent. This represents
815 // the input value in its whole number representation.
816 // 2) Apply an additional scale of 2 such that later comparisons against the margin values
817 // are simplified.
818 // 3) Set the margin value to the lowest mantissa bit's scale.
819
820 // scaledValue = 2 * 2 * mantissa*2^exponent
821 scaledValue.SetU64( 4 * mantissa );
822 BigInt_ShiftLeft( &scaledValue, exponent );
823
824 // scale = 2 * 2 * 1
825 scale.SetU32( 4 );
826
827 // scaledMarginLow = 2 * 2^(exponent-1)
828 BigInt_Pow2( &scaledMarginLow, exponent );
829
830 // scaledMarginHigh = 2 * 2 * 2^(exponent-1)
831 BigInt_Pow2( &optionalMarginHigh, exponent + 1 );
832 }
833 // else we have a fractional exponent
834 else
835 {
836 // In order to track the mantissa data as an integer, we store it as is with a large scale
837
838 // scaledValue = 2 * 2 * mantissa
839 scaledValue.SetU64( 4 * mantissa );
840
841 // scale = 2 * 2 * 2^(-exponent)
842 BigInt_Pow2(&scale, -exponent + 2 );
843
844 // scaledMarginLow = 2 * 2^(-1)
845 scaledMarginLow.SetU32( 1 );
846
847 // scaledMarginHigh = 2 * 2 * 2^(-1)
848 optionalMarginHigh.SetU32( 2 );
849 }
850
851 // the high and low margins are different
852 pScaledMarginHigh = &optionalMarginHigh;
853 }
854 else
855 {
856 // if we have no fractional component
857 if (exponent > 0)
5
Assuming 'exponent' is <= 0
6
Taking false branch
858 {
859 // 1) Expand the input value by multiplying out the mantissa and exponent. This represents
860 // the input value in its whole number representation.
861 // 2) Apply an additional scale of 2 such that later comparisons against the margin values
862 // are simplified.
863 // 3) Set the margin value to the lowest mantissa bit's scale.
864
865 // scaledValue = 2 * mantissa*2^exponent
866 scaledValue.SetU64( 2 * mantissa );
867 BigInt_ShiftLeft( &scaledValue, exponent );
868
869 // scale = 2 * 1
870 scale.SetU32( 2 );
871
872 // scaledMarginLow = 2 * 2^(exponent-1)
873 BigInt_Pow2( &scaledMarginLow, exponent );
874 }
875 // else we have a fractional exponent
876 else
877 {
878 // In order to track the mantissa data as an integer, we store it as is with a large scale
879
880 // scaledValue = 2 * mantissa
881 scaledValue.SetU64( 2 * mantissa );
882
883 // scale = 2 * 2^(-exponent)
884 BigInt_Pow2(&scale, -exponent + 1 );
885
886 // scaledMarginLow = 2 * 2^(-1)
887 scaledMarginLow.SetU32( 1 );
888 }
889
890 // the high and low margins are equal
891 pScaledMarginHigh = &scaledMarginLow;
892 }
893
894 // Compute an estimate for digitExponent that will be correct or undershoot by one.
895 // This optimization is based on the paper "Printing Floating-Point Numbers Quickly and Accurately"
896 // by Burger and Dybvig http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.72.4656&rep=rep1&type=pdf
897 // We perform an additional subtraction of 0.69 to increase the frequency of a failed estimate
898 // because that lets us take a faster branch in the code. 0.69 is chosen because 0.69 + log10(2) is
899 // less than one by a reasonable epsilon that will account for any floating point error.
900 //
901 // We want to set digitExponent to floor(log10(v)) + 1
902 // v = mantissa*2^exponent
903 // log2(v) = log2(mantissa) + exponent;
904 // log10(v) = log2(v) * log10(2)
905 // floor(log2(v)) = mantissaHighBitIdx + exponent;
906 // log10(v) - log10(2) < (mantissaHighBitIdx + exponent) * log10(2) <= log10(v)
907 // log10(v) < (mantissaHighBitIdx + exponent) * log10(2) + log10(2) <= log10(v) + log10(2)
908 // floor( log10(v) ) < ceil( (mantissaHighBitIdx + exponent) * log10(2) ) <= floor( log10(v) ) + 1
909 const tF64 log10_2 = 0.30102999566398119521373889472449;
910 tS32 digitExponent = (tS32)(ceil(tF64((tS32)mantissaHighBitIdx + exponent) * log10_2 - 0.69));
911
912 // if the digit exponent is smaller than the smallest desired digit for fractional cutoff,
913 // pull the digit back into legal range at which point we will round to the appropriate value.
914 // Note that while our value for digitExponent is still an estimate, this is safe because it
915 // only increases the number. This will either correct digitExponent to an accurate value or it
916 // will clamp it above the accurate value.
917 if (cutoffMode == CutoffMode_FractionLength && digitExponent <= -(tS32)cutoffNumber)
7
Assuming 'cutoffMode' is not equal to CutoffMode_FractionLength
918 {
919 digitExponent = -(tS32)cutoffNumber + 1;
920 }
921
922 // Divide value by 10^digitExponent.
923 if (digitExponent > 0)
8
Assuming 'digitExponent' is <= 0
9
Taking false branch
924 {
925 // The exponent is positive creating a division so we multiply up the scale.
926 tBigInt temp;
927 BigInt_MultiplyPow10( &temp, scale, digitExponent );
928 scale = temp;
929 }
930 else if (digitExponent < 0)
10
Assuming 'digitExponent' is >= 0
11
Taking false branch
931 {
932 // The exponent is negative creating a multiplication so we multiply up the scaledValue,
933 // scaledMarginLow and scaledMarginHigh.
934 tBigInt pow10;
935 BigInt_Pow10( &pow10, -digitExponent);
936
937 tBigInt temp;
938 BigInt_Multiply( &temp, scaledValue, pow10);
939 scaledValue = temp;
940
941 BigInt_Multiply( &temp, scaledMarginLow, pow10);
942 scaledMarginLow = temp;
943
944 if (pScaledMarginHigh != &scaledMarginLow)
945 BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow );
946 }
947
948 // If (value + marginHigh) >= 1, our estimate for digitExponent was too low
949 tBigInt scaledValueHigh;
950 BigInt_Add( &scaledValueHigh, scaledValue, *pScaledMarginHigh );
951 if( BigInt_Compare(scaledValueHigh,scale) >= 0 )
12
Taking false branch
952 {
953 // The exponent estimate was incorrect.
954 // Increment the exponent and don't perform the premultiply needed
955 // for the first loop iteration.
956 digitExponent = digitExponent + 1;
957 }
958 else
959 {
960 // The exponent estimate was correct.
961 // Multiply larger by the output base to prepare for the first loop iteration.
962 BigInt_Multiply10( &scaledValue );
13
Calling 'BigInt_Multiply10'
16
Returning from 'BigInt_Multiply10'
963 BigInt_Multiply10( &scaledMarginLow );
964 if (pScaledMarginHigh != &scaledMarginLow)
17
Taking false branch
965 BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow );
966 }
967
968 // Compute the cutoff exponent (the exponent of the final digit to print).
969 // Default to the maximum size of the output buffer.
970 tS32 cutoffExponent = digitExponent - bufferSize;
971 switch(cutoffMode)
18
Control jumps to 'case CutoffMode_TotalLength:' at line 978
972 {
973 // print digits until we pass the accuracy margin limits or buffer size
974 case CutoffMode_Unique:
975 break;
976
977 // print cutoffNumber of digits or until we reach the buffer size
978 case CutoffMode_TotalLength:
979 {
980 tS32 desiredCutoffExponent = digitExponent - (tS32)cutoffNumber;
981 if (desiredCutoffExponent > cutoffExponent)
19
Taking false branch
982 cutoffExponent = desiredCutoffExponent;
983 }
984 break;
20
Execution continues on line 997
985
986 // print cutoffNumber digits past the decimal point or until we reach the buffer size
987 case CutoffMode_FractionLength:
988 {
989 tS32 desiredCutoffExponent = -(tS32)cutoffNumber;
990 if (desiredCutoffExponent > cutoffExponent)
991 cutoffExponent = desiredCutoffExponent;
992 }
993 break;
994 }
995
996 // Output the exponent of the first digit we will print
997 *pOutExponent = digitExponent-1;
998
999 // In preparation for calling BigInt_DivideWithRemainder_MaxQuotient9(),
1000 // we need to scale up our values such that the highest block of the denominator
1001 // is greater than or equal to 8. We also need to guarantee that the numerator
1002 // can never have a length greater than the denominator after each loop iteration.
1003 // This requires the highest block of the denominator to be less than or equal to
1004 // 429496729 which is the highest number that can be multiplied by 10 without
1005 // overflowing to a new block.
1006 RJ_ASSERT( scale.GetLength() > 0 );
1007 tU32 hiBlock = scale.GetBlock( scale.GetLength() - 1 );
1008 if (hiBlock < 8 || hiBlock > 429496729)
21
Assuming 'hiBlock' is >= 8
22
Assuming 'hiBlock' is > 429496729
23
Taking true branch
1009 {
1010 // Perform a bit shift on all values to get the highest block of the denominator into
1011 // the range [8,429496729]. We are more likely to make accurate quotient estimations
1012 // in BigInt_DivideWithRemainder_MaxQuotient9() with higher denominator values so
1013 // we shift the denominator to place the highest bit at index 27 of the highest block.
1014 // This is safe because (2^28 - 1) = 268435455 which is less than 429496729. This means
1015 // that all values with a highest bit at index 27 are within range.
1016 tU32 hiBlockLog2 = LogBase2(hiBlock);
1017 RJ_ASSERT(hiBlockLog2 < 3 || hiBlockLog2 > 27);
1018 tU32 shift = (32 + 27 - hiBlockLog2) % 32;
1019
1020 BigInt_ShiftLeft( &scale, shift );
1021 BigInt_ShiftLeft( &scaledValue, shift);
24
Calling 'BigInt_ShiftLeft'
29
Returning from 'BigInt_ShiftLeft'
1022 BigInt_ShiftLeft( &scaledMarginLow, shift);
1023 if (pScaledMarginHigh != &scaledMarginLow)
30
Taking false branch
1024 BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow );
1025 }
1026
1027 // These values are used to inspect why the print loop terminated so we can properly
1028 // round the final digit.
1029 tB low; // did the value get within marginLow distance from zero
1030 tB high; // did the value get within marginHigh distance from one
1031 tU32 outputDigit; // current digit being output
1032
1033 if (cutoffMode == CutoffMode_Unique)
31
Taking false branch
1034 {
1035 // For the unique cutoff mode, we will try to print until we have reached a level of
1036 // precision that uniquely distinguishes this value from its neighbors. If we run
1037 // out of space in the output buffer, we terminate early.
1038 for (;;)
1039 {
1040 digitExponent = digitExponent-1;
1041
1042 // divide out the scale to extract the digit
1043 outputDigit = BigInt_DivideWithRemainder_MaxQuotient9(&scaledValue, scale);
1044 RJ_ASSERT( outputDigit < 10 );
1045
1046 // update the high end of the value
1047 BigInt_Add( &scaledValueHigh, scaledValue, *pScaledMarginHigh );
1048
1049 // stop looping if we are far enough away from our neighboring values
1050 // or if we have reached the cutoff digit
1051 low = BigInt_Compare(scaledValue, scaledMarginLow) < 0;
1052 high = BigInt_Compare(scaledValueHigh, scale) > 0;
1053 if (low | high | (digitExponent == cutoffExponent))
1054 break;
1055
1056 // store the output digit
1057 *pCurDigit = (tC8)('0' + outputDigit);
1058 ++pCurDigit;
1059
1060 // multiply larger by the output base
1061 BigInt_Multiply10( &scaledValue );
1062 BigInt_Multiply10( &scaledMarginLow );
1063 if (pScaledMarginHigh != &scaledMarginLow)
1064 BigInt_Multiply2( pScaledMarginHigh, scaledMarginLow );
1065 }
1066 }
1067 else
1068 {
1069 // For length based cutoff modes, we will try to print until we
1070 // have exhausted all precision (i.e. all remaining digits are zeros) or
1071 // until we reach the desired cutoff digit.
1072 low = false;
1073 high = false;
1074
1075 for (;;)
32
Loop condition is true. Entering loop body
1076 {
1077 digitExponent = digitExponent-1;
1078
1079 // divide out the scale to extract the digit
1080 outputDigit = BigInt_DivideWithRemainder_MaxQuotient9(&scaledValue, scale);
33
Calling 'BigInt_DivideWithRemainder_MaxQuotient9'
1081 RJ_ASSERT( outputDigit < 10 );
1082
1083 if ( scaledValue.IsZero() | (digitExponent == cutoffExponent) )
1084 break;
1085
1086 // store the output digit
1087 *pCurDigit = (tC8)('0' + outputDigit);
1088 ++pCurDigit;
1089
1090 // multiply larger by the output base
1091 BigInt_Multiply10(&scaledValue);
1092 }
1093 }
1094
1095 // round off the final digit
1096 // default to rounding down if value got too close to 0
1097 tB roundDown = low;
1098
1099 // if it is legal to round up and down
1100 if (low == high)
1101 {
1102 // round to the closest digit by comparing value with 0.5. To do this we need to convert
1103 // the inequality to large integer values.
1104 // compare( value, 0.5 )
1105 // compare( scale * value, scale * 0.5 )
1106 // compare( 2 * scale * value, scale )
1107 BigInt_Multiply2(&scaledValue);
1108 tS32 compare = BigInt_Compare(scaledValue, scale);
1109 roundDown = compare < 0;
1110
1111 // if we are directly in the middle, round towards the even digit (i.e. IEEE rouding rules)
1112 if (compare == 0)
1113 roundDown = (outputDigit & 1) == 0;
1114 }
1115
1116 // print the rounded digit
1117 if (roundDown)
1118 {
1119 *pCurDigit = (tC8)('0' + outputDigit);
1120 ++pCurDigit;
1121 }
1122 else
1123 {
1124 // handle rounding up
1125 if (outputDigit == 9)
1126 {
1127 // find the first non-nine prior digit
1128 for (;;)
1129 {
1130 // if we are at the first digit
1131 if (pCurDigit == pOutBuffer)
1132 {
1133 // output 1 at the next highest exponent
1134 *pCurDigit = '1';
1135 ++pCurDigit;
1136 *pOutExponent += 1;
1137 break;
1138 }
1139
1140 --pCurDigit;
1141 if (*pCurDigit != '9')
1142 {
1143 // increment the digit
1144 *pCurDigit += 1;
1145 ++pCurDigit;
1146 break;
1147 }
1148 }
1149 }
1150 else
1151 {
1152 // values in the range [0,8] can perform a simple round up
1153 *pCurDigit = (tC8)('0' + outputDigit + 1);
1154 ++pCurDigit;
1155 }
1156 }
1157
1158 // return the number of digits output
1159 RJ_ASSERT(pCurDigit - pOutBuffer <= (tPtrDiff)bufferSize);
1160 return pCurDigit - pOutBuffer;
1161}
diff --git a/scan-build/report-cc9ed8.html b/scan-build/report-cc9ed8.html deleted file mode 100644 index 5979d5bb..00000000 --- a/scan-build/report-cc9ed8.html +++ /dev/null @@ -1,488 +0,0 @@ - - - -lib/real/kremp2.c - - - - - - - - - - - - - - - - - - - - - - - - - -

Bug Summary

- - - - -
File:real/kremp2.c
Location:line 351, column 18
Description:Assigned value is garbage or undefined
- -

Annotated Source Code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/* @(#)k_rem_pio2.c 1.3 95/01/18 */
2
3/*
4 * Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * The origin source code can be obtained from:
28 * http://www.netlib.org/fdlibm/k_rem_pio2.c
29 *
30 */
31
32/*
33 * ====================================================
34 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
35 *
36 * Developed at SunSoft, a Sun Microsystems, Inc. business.
37 * Permission to use, copy, modify, and distribute this
38 * software is freely granted, provided that this notice
39 * is preserved.
40 * ====================================================
41 */
42
43#include "prim.h"
44#include "math.h"
45
46/*
47 * Constants:
48 * The hexadecimal values are the intended ones for the following
49 * constants. The decimal values may be used, provided that the
50 * compiler will convert from decimal to binary accurately enough
51 * to produce the hexadecimal values shown.
52 */
53
54static const int init_jk[] = {2,3,4,6}; /* initial value for jk */
55
56static const double PIo2[] = {
57 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
58 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
59 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
60 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
61 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
62 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
63 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
64 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
65};
66
67static const double
68zero = 0.0,
69one = 1.0,
70two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
71twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
72
73/**
74 * @brief Kernel reduction function.
75 * @version 1.4
76 * @date 96/03/07
77 * @details
78 * <pre>
79 * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
80 * double x[],y[]; int e0,nx,prec; int ipio2[];
81 *
82 * __kernel_rem_pio2 return the last three digits of N with
83 * y = x - N*pi/2
84 * so that |y| < pi/2.
85 *
86 * The method is to compute the integer (mod 8) and fraction parts of
87 * (2/pi)*x without doing the full multiplication. In general we
88 * skip the part of the product that are known to be a huge integer (
89 * more accurately, = 0 mod 8 ). Thus the number of operations are
90 * independent of the exponent of the input.
91 *
92 * (2/pi) is represented by an array of 24-bit integers in ipio2[].
93 *
94 * Input parameters:
95 * x[] The input value (must be positive) is broken into nx
96 * pieces of 24-bit integers in double precision format.
97 * x[i] will be the i-th 24 bit of x. The scaled exponent
98 * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
99 * match x's up to 24 bits.
100 *
101 * Example of breaking a double positive z into x[0]+x[1]+x[2]:
102 * e0 = ilogb(z)-23
103 * z = scalbn(z,-e0)
104 * for i = 0,1,2
105 * x[i] = floor(z)
106 * z = (z-x[i])*2**24
107 *
108 *
109 * y[] ouput result in an array of double precision numbers.
110 * The dimension of y[] is:
111 * 24-bit precision 1
112 * 53-bit precision 2
113 * 64-bit precision 2
114 * 113-bit precision 3
115 * The actual value is the sum of them. Thus for 113-bit
116 * precison, one may have to do something like:
117 *
118 * long double t,w,r_head, r_tail;
119 * t = (long double)y[2] + (long double)y[1];
120 * w = (long double)y[0];
121 * r_head = t+w;
122 * r_tail = w - (r_head - t);
123 *
124 * e0 The exponent of x[0]
125 *
126 * nx dimension of x[]
127 *
128 * prec an integer indicating the precision:
129 * 0 24 bits (single)
130 * 1 53 bits (double)
131 * 2 64 bits (extended)
132 * 3 113 bits (quad)
133 *
134 * ipio2[]
135 * integer array, contains the (24*i)-th to (24*i+23)-th
136 * bit of 2/pi after binary point. The corresponding
137 * floating value is
138 *
139 * ipio2[i] * 2^(-24(i+1)).
140 *
141 * External function:
142 * double scalbn(), floor();
143 *
144 *
145 * Here is the description of some local variables:
146 *
147 * jk jk+1 is the initial number of terms of ipio2[] needed
148 * in the computation. The recommended value is 2,3,4,
149 * 6 for single, double, extended,and quad.
150 *
151 * jz local integer variable indicating the number of
152 * terms of ipio2[] used.
153 *
154 * jx nx - 1
155 *
156 * jv index for pointing to the suitable ipio2[] for the
157 * computation. In general, we want
158 * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
159 * is an integer. Thus
160 * e0-3-24*jv >= 0 or (e0-3)/24 >= jv
161 * Hence jv = max(0,(e0-3)/24).
162 *
163 * jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
164 *
165 * q[] double array with integral value, representing the
166 * 24-bits chunk of the product of x and 2/pi.
167 *
168 * q0 the corresponding exponent of q[0]. Note that the
169 * exponent for q[i] would be q0-24*i.
170 *
171 * PIo2[] double precision array, obtained by cutting pi/2
172 * into 24 bits chunks.
173 *
174 * f[] ipio2[] in floating point
175 *
176 * iq[] integer array by breaking up q[] in 24-bits chunk.
177 *
178 * fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
179 *
180 * ih integer. If >0 it indicates q[] is >= 0.5, hence
181 * it also indicates the *sign* of the result.
182 *
183 * </pre>
184 * @copyright Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
185 * @license Developed at SunSoft, a Sun Microsystems, Inc. business. Permission
186 * to use, copy, modify, and distribute this software is freely granted,
187 * provided that this notice is preserved.
188 */
189
190int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int *ipio2)
191{
192 int jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
193 double z,fw,f[20],fq[20],q[20];
194
195 /* initialize jk*/
196 jk = init_jk[prec];
197 jp = jk;
198
199 /* determine jx,jv,q0, note that 3>q0 */
200 jx = nx-1;
201 jv = (e0-3)/24;
202 if(jv<0) jv=0;
1
Assuming 'jv' is >= 0
2
Taking false branch
203 q0 = e0-24*(jv+1);
204
205 /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
206 j = jv-jx;
207 m = jx+jk;
208 for(i=0; i<=m; i++,j++) f[i] = (j<0)? zero : (double) ipio2[j];
3
Assuming 'i' is > 'm'
4
Loop condition is false. Execution continues on line 211
209
210 /* compute q[0],q[1],...q[jk] */
211 for (i=0; i<=jk; i++) {
5
Assuming 'i' is > 'jk'
6
Loop condition is false. Execution continues on line 216
212 for(j=0,fw=0.0; j<=jx; j++) fw += x[j]*f[jx+i-j];
213 q[i] = fw;
214 }
215
216 jz = jk;
217recompute:
218 /* distill q[] into iq[] reversingly */
219 for(i=0,j=jz,z=q[jz]; j>0; i++,j--) {
7
Loop condition is false. Execution continues on line 226
21
Assuming 'j' is <= 0
22
Loop condition is false. Execution continues on line 226
220 fw = (double)((int)(twon24* z));
221 iq[i] = (int)(z-two24*fw);
222 z = q[j-1]+fw;
223 }
224
225 /* compute n */
226 z = scalbn(z,q0); /* actual value of z */
227 z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */
228 n = (int) z;
229 z -= (double)n;
230 ih = 0;
231 if(q0>0) { /* need iq[jz-1] to determine n */
8
Assuming 'q0' is <= 0
9
Taking false branch
23
Taking false branch
232 i = (iq[jz-1]>>(24-q0));
233 n += i;
234 iq[jz-1] -= i<<(24-q0);
235 ih = iq[jz-1]>>(23-q0);
236 }
237 else if(q0==0) ih = iq[jz-1]>>23;
10
Assuming 'q0' is not equal to 0
11
Taking false branch
24
Taking false branch
238 else if(z>=0.5) ih=2;
12
Taking false branch
25
Taking true branch
239
240 if(ih>0) { /* q > 0.5 */
13
Taking false branch
26
Taking true branch
241 n += 1;
242 carry = 0;
243 for(i=0; i<jz ; i++) { /* compute 1-q */
27
Loop condition is false. Execution continues on line 252
244 j = iq[i];
245 if(carry==0) {
246 if(j!=0) {
247 carry = 1;
248 iq[i] = 0x1000000- j;
249 }
250 } else iq[i] = 0xffffff - j;
251 }
252 if(q0>0) { /* rare case: chance is 1 in 12 */
28
Taking false branch
253 switch(q0) {
254 case 1:
255 iq[jz-1] &= 0x7fffff;
256 break;
257 case 2:
258 iq[jz-1] &= 0x3fffff;
259 break;
260 }
261 }
262 if(ih==2) {
29
Taking true branch
263 z = one - z;
264 if(carry!=0) z -= scalbn(one,q0);
30
Taking false branch
265 }
266 }
267
268 /* check if recomputation is needed */
269 if(z==zero) {
14
Taking true branch
31
Taking false branch
270 j = 0;
271 for (i=jz-1; i>=jk; i--) j |= iq[i];
15
Loop condition is false. Execution continues on line 272
272 if(j==0) { /* need recomputation */
16
Taking true branch
273 for(k=1; iq[jk-k]==0; k++); /* k = no. of terms needed */
17
Loop condition is true. Entering loop body
18
Loop condition is false. Execution continues on line 275
274
275 for(i=jz+1; i<=jz+k; i++) { /* add q[jz+1] to q[jz+k] */
19
Loop condition is false. Execution continues on line 280
276 f[jx+i] = (double) ipio2[jv+i];
277 for(j=0,fw=0.0; j<=jx; j++) fw += x[j]*f[jx+i-j];
278 q[i] = fw;
279 }
280 jz += k;
281 goto recompute;
20
Control jumps to line 219
282 }
283 }
284
285 /* chop off zero terms */
286 if(z==0.0) {
32
Taking false branch
287 jz -= 1;
288 q0 -= 24;
289 while(iq[jz]==0) {
290 jz--;
291 q0-=24;
292 }
293 } else { /* break z into 24-bit if necessary */
294 z = scalbn(z,-q0);
295 if(z>=two24) {
33
Taking false branch
296 fw = (double)((int)(twon24*z));
297 iq[jz] = (int)(z-two24*fw);
298 jz += 1;
299 q0 += 24;
300 iq[jz] = (int) fw;
301 } else iq[jz] = (int) z ;
302 }
303
304 /* convert integer "bit" chunk to floating-point value */
305 fw = scalbn(one,q0);
306 for(i=jz; i>=0; i--) {
34
Assuming 'i' is >= 0
35
Loop condition is true. Entering loop body
36
Loop condition is false. Execution continues on line 312
307 q[i] = fw*(double)iq[i];
308 fw*=twon24;
309 }
310
311 /* compute PIo2[0,...,jp]*q[jz,...,0] */
312 for(i=jz; i>=0; i--) {
37
Loop condition is true. Entering loop body
38
Loop condition is false. Execution continues on line 318
313 for(fw=0.0,k=0; k<=jp&&k<=jz-i; k++) fw += PIo2[k]*q[i+k];
314 fq[jz-i] = fw;
315 }
316
317 /* compress fq[] into y[] */
318 switch(prec) {
39
Control jumps to 'case 3:' at line 333
319 case 0:
320 fw = 0.0;
321 for (i=jz; i>=0; i--) fw += fq[i];
322 y[0] = (ih==0)? fw: -fw;
323 break;
324 case 1:
325 case 2:
326 fw = 0.0;
327 for (i=jz; i>=0; i--) fw += fq[i];
328 y[0] = (ih==0)? fw: -fw;
329 fw = fq[0]-fw;
330 for (i=1; i<=jz; i++) fw += fq[i];
331 y[1] = (ih==0)? fw: -fw;
332 break;
333 case 3: /* painful */
334 for (i=jz; i>0; i--) {
40
Loop condition is false. Execution continues on line 339
335 fw = fq[i-1]+fq[i];
336 fq[i] += fq[i-1]-fw;
337 fq[i-1] = fw;
338 }
339 for (i=jz; i>1; i--) {
41
Loop condition is false. Execution continues on line 344
340 fw = fq[i-1]+fq[i];
341 fq[i] += fq[i-1]-fw;
342 fq[i-1] = fw;
343 }
344 for (fw=0.0,i=jz; i>=2; i--) fw += fq[i];
42
Loop condition is false. Execution continues on line 345
345 if(ih==0) {
43
Taking false branch
346 y[0] = fq[0];
347 y[1] = fq[1];
348 y[2] = fw;
349 } else {
350 y[0] = -fq[0];
351 y[1] = -fq[1];
44
Assigned value is garbage or undefined
352 y[2] = -fw;
353 }
354 }
355 return n&7;
356}
diff --git a/scan-build/report-e79f68.html b/scan-build/report-e79f68.html deleted file mode 100644 index c38344c0..00000000 --- a/scan-build/report-e79f68.html +++ /dev/null @@ -1,349 +0,0 @@ - - - -lib/real/expm1.c - - - - - - - - - - - - - - - - - - - - - - - - - -

Bug Summary

- - - - -
File:real/expm1.c
Location:line 166, column 16
Description:Value stored to 'y' is never read
- -

Annotated Source Code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/* @(#)s_expm1.c 1.5 04/04/22 */
2
3/*
4 * Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * The origin source code can be obtained from:
28 * http://www.netlib.org/fdlibm/s_expm1.c
29 *
30 */
31
32/*
33 * ====================================================
34 * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
35 *
36 * Permission to use, copy, modify, and distribute this
37 * software is freely granted, provided that this notice
38 * is preserved.
39 * ====================================================
40 *
41 */
42
43#include "prim.h"
44#include "math.h"
45
46/* expm1(x)
47 * Returns exp(x)-1, the exponential of x minus 1.
48 *
49 * Method
50 * 1. Argument reduction:
51 * Given x, find r and integer k such that
52 *
53 * x = k*ln2 + r, |r| <= 0.5*ln2 ~ 0.34658
54 *
55 * Here a correction term c will be computed to compensate
56 * the error in r when rounded to a floating-point number.
57 *
58 * 2. Approximating expm1(r) by a special rational function on
59 * the interval [0,0.34658]:
60 * Since
61 * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ...
62 * we define R1(r*r) by
63 * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r)
64 * That is,
65 * R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
66 * = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
67 * = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
68 * We use a special Remes algorithm on [0,0.347] to generate
69 * a polynomial of degree 5 in r*r to approximate R1. The
70 * maximum error of this polynomial approximation is bounded
71 * by 2**-61. In other words,
72 * R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5
73 * where Q1 = -1.6666666666666567384E-2,
74 * Q2 = 3.9682539681370365873E-4,
75 * Q3 = -9.9206344733435987357E-6,
76 * Q4 = 2.5051361420808517002E-7,
77 * Q5 = -6.2843505682382617102E-9;
78 * (where z=r*r, and the values of Q1 to Q5 are listed below)
79 * with error bounded by
80 * | 5 | -61
81 * | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2
82 * | |
83 *
84 * expm1(r) = exp(r)-1 is then computed by the following
85 * specific way which minimize the accumulation rounding error:
86 * 2 3
87 * r r [ 3 - (R1 + R1*r/2) ]
88 * expm1(r) = r + --- + --- * [--------------------]
89 * 2 2 [ 6 - r*(3 - R1*r/2) ]
90 *
91 * To compensate the error in the argument reduction, we use
92 * expm1(r+c) = expm1(r) + c + expm1(r)*c
93 * ~ expm1(r) + c + r*c
94 * Thus c+r*c will be added in as the correction terms for
95 * expm1(r+c). Now rearrange the term to avoid optimization
96 * screw up:
97 * ( 2 2 )
98 * ({ ( r [ R1 - (3 - R1*r/2) ] ) } r )
99 * expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- )
100 * ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 )
101 * ( )
102 *
103 * = r - E
104 * 3. Scale back to obtain expm1(x):
105 * From step 1, we have
106 * expm1(x) = either 2^k*[expm1(r)+1] - 1
107 * = or 2^k*[expm1(r) + (1-2^-k)]
108 * 4. Implementation notes:
109 * (A). To save one multiplication, we scale the coefficient Qi
110 * to Qi*2^i, and replace z by (x^2)/2.
111 * (B). To achieve maximum accuracy, we compute expm1(x) by
112 * (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf)
113 * (ii) if k=0, return r-E
114 * (iii) if k=-1, return 0.5*(r-E)-0.5
115 * (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E)
116 * else return 1.0+2.0*(r-E);
117 * (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1)
118 * (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else
119 * (vii) return 2^k(1-((E+2^-k)-r))
120 *
121 * Special cases:
122 * expm1(INF) is INF, expm1(NaN) is NaN;
123 * expm1(-INF) is -1, and
124 * for finite argument, only expm1(0)=0 is exact.
125 *
126 * Accuracy:
127 * according to an error analysis, the error is always less than
128 * 1 ulp (unit in the last place).
129 *
130 * Misc. info.
131 * For IEEE double
132 * if x > 7.09782712893383973096e+02 then expm1(x) overflow
133 *
134 * Constants:
135 * The hexadecimal values are the intended ones for the following
136 * constants. The decimal values may be used, provided that the
137 * compiler will convert from decimal to binary accurately enough
138 * to produce the hexadecimal values shown.
139 */
140
141static const double
142one = 1.0,
143huge = 1.0e+300,
144tiny = 1.0e-300,
145o_threshold = 7.09782712893383973096e+02,/* 0x40862E42, 0xFEFA39EF */
146ln2_hi = 6.93147180369123816490e-01,/* 0x3fe62e42, 0xfee00000 */
147ln2_lo = 1.90821492927058770002e-10,/* 0x3dea39ef, 0x35793c76 */
148invln2 = 1.44269504088896338700e+00,/* 0x3ff71547, 0x652b82fe */
149 /* scaled coefficients related to expm1 */
150Q1 = -3.33333333333331316428e-02, /* BFA11111 111110F4 */
151Q2 = 1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */
152Q3 = -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */
153Q4 = 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */
154Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */
155
156double expm1(double x)
157{
158 double y,hi,lo,c,t,e,hxs,hfx,r1;
159 sword k,xsb;
160 uword hx;
161
162 c = 0.0;
163
164 GET_HIGH_WORD(hx,x)do { ieee_double_shape_type gh_u; gh_u.value = (x); (hx) = gh_u
.parts.msw; } while (0)
; /* high word of x */
165 xsb = hx&0x80000000; /* sign bit of x */
166 if(xsb==0) y=x;
Value stored to 'y' is never read
167 else y= -x; /* y = |x| */
168 hx &= 0x7fffffff; /* high word of |x| */
169
170 /* filter out huge and non-finite argument */
171 if(hx >= 0x4043687A) { /* if |x|>=56*ln2 */
172 if(hx >= 0x40862E42) { /* if |x|>=709.78... */
173 if(hx>=0x7ff00000) {
174 uword low;
175 GET_LOW_WORD(low,x)do { ieee_double_shape_type gl_u; gl_u.value = (x); (low) = gl_u
.parts.lsw; } while (0)
;
176 if(((hx&0xfffff)|low)!=0)
177 return x+x; /* NaN */
178 else return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */
179 }
180 if(x > o_threshold) return huge*huge; /* overflow */
181 }
182 if(xsb!=0) { /* x < -56*ln2, return -1.0 with inexact */
183 if(x+tiny<0.0) /* raise inexact */
184 return tiny-one; /* return -1 */
185 }
186 }
187
188 /* argument reduction */
189 if(hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
190 if(hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
191 if(xsb==0)
192 {
193 hi = x - ln2_hi;
194 lo = ln2_lo;
195 k = 1;
196 }
197 else
198 {
199 hi = x + ln2_hi;
200 lo = -ln2_lo;
201 k = -1;
202 }
203 } else {
204 k = (sword)(invln2*x+((xsb==0)?0.5:-0.5));
205 t = k;
206 hi = x - t*ln2_hi; /* t*ln2_hi is exact here */
207 lo = t*ln2_lo;
208 }
209 x = hi - lo;
210 c = (hi-x)-lo;
211 }
212 else if(hx < 0x3c900000) { /* when |x|<2**-54, return x */
213 t = huge+x; /* return x with inexact flags when x!=0 */
214 return x - (t-(huge+x));
215 }
216 else k = 0;
217
218 /* x is now in primary range */
219 hfx = 0.5*x;
220 hxs = x*hfx;
221 r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))));
222 t = 3.0-r1*hfx;
223 e = hxs*((r1-t)/(6.0 - x*t));
224 if(k==0) return x - (x*e-hxs); /* c is 0 */
225 else {
226 e = (x*(e-c)-c);
227 e -= hxs;
228 if(k== -1) return 0.5*(x-e)-0.5;
229 if(k==1) {
230 if(x < -0.25) return -2.0*(e-(x+0.5));
231 else return one+2.0*(x-e);
232 }
233 if (k <= -2 || k>56) { /* suffice to return exp(x)-1 */
234 uword hy;
235
236 y = one-(e-x);
237 GET_HIGH_WORD(hy,y)do { ieee_double_shape_type gh_u; gh_u.value = (y); (hy) = gh_u
.parts.msw; } while (0)
;
238 SET_HIGH_WORD(y, hy + (k<<20))do { ieee_double_shape_type sh_u; sh_u.value = (y); sh_u.parts
.msw = (hy + (k<<20)); (y) = sh_u.value; } while (0)
; /* add k to y's exponent */
239 return y-one;
240 }
241 t = one;
242 if(k<20) {
243 uword hy;
244
245 SET_HIGH_WORD(t, 0x3ff00000 - (0x200000>>k))do { ieee_double_shape_type sh_u; sh_u.value = (t); sh_u.parts
.msw = (0x3ff00000 - (0x200000>>k)); (t) = sh_u.value; }
while (0)
; /* t=1-2^-k */
246 y = t-(e-x);
247 GET_HIGH_WORD(hy, y)do { ieee_double_shape_type gh_u; gh_u.value = (y); (hy) = gh_u
.parts.msw; } while (0)
;
248 SET_HIGH_WORD(y, hy + (k<<20))do { ieee_double_shape_type sh_u; sh_u.value = (y); sh_u.parts
.msw = (hy + (k<<20)); (y) = sh_u.value; } while (0)
; /* add k to y's exponent */
249 } else {
250 uword hy;
251
252 SET_HIGH_WORD(t, (0x3ff-k)<<20)do { ieee_double_shape_type sh_u; sh_u.value = (t); sh_u.parts
.msw = ((0x3ff-k)<<20); (t) = sh_u.value; } while (0)
; /* 2^-k */
253 y = x-(e+t);
254 y += one;
255 GET_HIGH_WORD(hy, y)do { ieee_double_shape_type gh_u; gh_u.value = (y); (hy) = gh_u
.parts.msw; } while (0)
;
256 SET_HIGH_WORD(y, hy + (k<<20))do { ieee_double_shape_type sh_u; sh_u.value = (y); sh_u.parts
.msw = (hy + (k<<20)); (y) = sh_u.value; } while (0)
; /* add k to y's exponent */
257 }
258 }
259 return y;
260}
diff --git a/scan-build/report-e85ac2.html b/scan-build/report-e85ac2.html deleted file mode 100644 index ebaab250..00000000 --- a/scan-build/report-e85ac2.html +++ /dev/null @@ -1,313 +0,0 @@ - - - -lib/real/remp2.c - - - - - - - - - - - - - - - - - - - - - - - - - -

Bug Summary

- - - - -
File:real/remp2.c
Location:line 202, column 19
Description:The left operand of '==' is a garbage value
- -

Annotated Source Code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/* @(#)e_rem_pio2.c 1.4 95/01/18 */
2
3/*
4 * Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * The origin source code can be obtained from:
28 * http://www.netlib.org/fdlibm/e_rem_pio2.c
29 *
30 */
31
32/*
33 * ====================================================
34 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
35 *
36 * Developed at SunSoft, a Sun Microsystems, Inc. business.
37 * Permission to use, copy, modify, and distribute this
38 * software is freely granted, provided that this notice
39 * is preserved.
40 * ====================================================
41 *
42 */
43
44#include "prim.h"
45#include "math.h"
46
47/* rem_pio2(x,y)
48 *
49 * return the remainder of x rem pi/2 in y[0]+y[1]
50 * use __kernel_rem_pio2()
51 */
52
53
54/*
55 * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
56 */
57
58static const int two_over_pi[] = {
59 0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62,
60 0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A,
61 0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
62 0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41,
63 0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8,
64 0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF,
65 0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
66 0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08,
67 0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3,
68 0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,
69 0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B,
70};
71
72static const int npio2_hw[] = {
73 0x3FF921FB, 0x400921FB, 0x4012D97C, 0x401921FB, 0x401F6A7A, 0x4022D97C,
74 0x4025FDBB, 0x402921FB, 0x402C463A, 0x402F6A7A, 0x4031475C, 0x4032D97C,
75 0x40346B9C, 0x4035FDBB, 0x40378FDB, 0x403921FB, 0x403AB41B, 0x403C463A,
76 0x403DD85A, 0x403F6A7A, 0x40407E4C, 0x4041475C, 0x4042106C, 0x4042D97C,
77 0x4043A28C, 0x40446B9C, 0x404534AC, 0x4045FDBB, 0x4046C6CB, 0x40478FDB,
78 0x404858EB, 0x404921FB,
79};
80
81/*
82 * invpio2: 53 bits of 2/pi
83 * pio2_1: first 33 bit of pi/2
84 * pio2_1t: pi/2 - pio2_1
85 * pio2_2: second 33 bit of pi/2
86 * pio2_2t: pi/2 - (pio2_1+pio2_2)
87 * pio2_3: third 33 bit of pi/2
88 * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
89 */
90
91static const double
92zero = 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
93half = 5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
94two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
95invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
96pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
97pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
98pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
99pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
100pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
101pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
102
103int rempio2(double x, double *y)
104{
105 double z = 0.,w,t,r,fn;
106 double tx[3];
107 sword i,j,n,ix,hx;
108 int e0,nx;
109 uword low;
110
111 GET_HIGH_WORD(hx,x)do { ieee_double_shape_type gh_u; gh_u.value = (x); (hx) = gh_u
.parts.msw; } while (0)
; /* high word of x */
112 ix = hx&0x7fffffff;
113 if(ix<=0x3fe921fb) /* |x| ~<= pi/4 , no need for reduction */
1
Assuming 'ix' is > 1072243195
2
Taking false branch
114 {
115 y[0] = x;
116 y[1] = 0;
117 return 0;
118 }
119 if(ix<0x4002d97c) { /* |x| < 3pi/4, special case with n=+-1 */
3
Assuming 'ix' is >= 1073928572
4
Taking false branch
120 if(hx>0) {
121 z = x - pio2_1;
122 if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */
123 y[0] = z - pio2_1t;
124 y[1] = (z-y[0])-pio2_1t;
125 } else { /* near pi/2, use 33+33+53 bit pi */
126 z -= pio2_2;
127 y[0] = z - pio2_2t;
128 y[1] = (z-y[0])-pio2_2t;
129 }
130 return 1;
131 } else { /* negative x */
132 z = x + pio2_1;
133 if(ix!=0x3ff921fb) { /* 33+53 bit pi is good enough */
134 y[0] = z + pio2_1t;
135 y[1] = (z-y[0])+pio2_1t;
136 } else { /* near pi/2, use 33+33+53 bit pi */
137 z += pio2_2;
138 y[0] = z + pio2_2t;
139 y[1] = (z-y[0])+pio2_2t;
140 }
141 return -1;
142 }
143 }
144 if(ix<=0x413921fb) { /* |x| ~<= 2^19*(pi/2), medium size */
5
Assuming 'ix' is > 1094263291
6
Taking false branch
145 t = fabs(x);
146 n = (sword) (t*invpio2+half);
147 fn = (double)n;
148 r = t-fn*pio2_1;
149 w = fn*pio2_1t; /* 1st round good to 85 bit */
150 if(n<32&&ix!=npio2_hw[n-1]) {
151 y[0] = r-w; /* quick check no cancellation */
152 } else {
153 uword high;
154
155 j = ix>>20;
156 y[0] = r-w;
157 GET_HIGH_WORD(high, y[0])do { ieee_double_shape_type gh_u; gh_u.value = (y[0]); (high)
= gh_u.parts.msw; } while (0)
;
158 i = j-((high>>20)&0x7ff);
159 if(i>16) { /* 2nd iteration needed, good to 118 */
160 t = r;
161 w = fn*pio2_2;
162 r = t-w;
163 w = fn*pio2_2t-((t-r)-w);
164 y[0] = r-w;
165 GET_HIGH_WORD(high,y[0])do { ieee_double_shape_type gh_u; gh_u.value = (y[0]); (high)
= gh_u.parts.msw; } while (0)
;
166 i = j-((high>>20)&0x7ff);
167 if(i>49) { /* 3rd iteration need, 151 bits acc */
168 t = r; /* will cover all possible cases */
169 w = fn*pio2_3;
170 r = t-w;
171 w = fn*pio2_3t-((t-r)-w);
172 y[0] = r-w;
173 }
174 }
175 }
176 y[1] = (r-y[0])-w;
177 if(hx<0) {
178 y[0] = -y[0];
179 y[1] = -y[1];
180 return -n;
181 }
182 else return n;
183 }
184 /*
185 * all other (large) arguments
186 */
187 if(ix>=0x7ff00000) { /* x is inf or NaN */
7
Assuming 'ix' is < 2146435072
8
Taking false branch
188 y[0]=y[1]=x-x;
189 return 0;
190 }
191 /* set z = scalbn(|x|,ilogb(x)-23) */
192 GET_LOW_WORD(low,x)do { ieee_double_shape_type gl_u; gl_u.value = (x); (low) = gl_u
.parts.lsw; } while (0)
;
193 SET_LOW_WORD(z,low)do { ieee_double_shape_type sl_u; sl_u.value = (z); sl_u.parts
.lsw = (low); (z) = sl_u.value; } while (0)
;
194 e0 = (sword)(ix>>20)-1046; /* e0 = ilogb(z)-23; */
195 SET_HIGH_WORD(z,ix - (e0<<20))do { ieee_double_shape_type sh_u; sh_u.value = (z); sh_u.parts
.msw = (ix - (e0<<20)); (z) = sh_u.value; } while (0)
;
196 for(i=0; i<2; i++) {
9
Loop condition is true. Entering loop body
10
Loop condition is true. Entering loop body
11
Loop condition is false. Execution continues on line 200
197 tx[i] = (double)((sword)(z));
198 z = (z-tx[i])*two24;
199 }
200 tx[2] = z;
201 nx = 3;
202 while(tx[nx-1]==zero) nx--; /* skip zero term */
12
Loop condition is true. Entering loop body
13
Loop condition is true. Entering loop body
14
Loop condition is true. Entering loop body
15
The left operand of '==' is a garbage value
203 n = __kernel_rem_pio2(tx,y,e0,nx,2,two_over_pi);
204 if(hx<0) {
205 y[0] = -y[0];
206 y[1] = -y[1];
207 return -n;
208 }
209 return n;
210}
diff --git a/scan-build/report-f61e62.html b/scan-build/report-f61e62.html deleted file mode 100644 index 9a304e77..00000000 --- a/scan-build/report-f61e62.html +++ /dev/null @@ -1,471 +0,0 @@ - - - -lib/real/kremp2.c - - - - - - - - - - - - - - - - - - - - - - - - - -

Bug Summary

- - - - -
File:real/kremp2.c
Location:line 347, column 18
Description:Assigned value is garbage or undefined
- -

Annotated Source Code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/* @(#)k_rem_pio2.c 1.3 95/01/18 */
2
3/*
4 * Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * The origin source code can be obtained from:
28 * http://www.netlib.org/fdlibm/k_rem_pio2.c
29 *
30 */
31
32/*
33 * ====================================================
34 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
35 *
36 * Developed at SunSoft, a Sun Microsystems, Inc. business.
37 * Permission to use, copy, modify, and distribute this
38 * software is freely granted, provided that this notice
39 * is preserved.
40 * ====================================================
41 */
42
43#include "prim.h"
44#include "math.h"
45
46/*
47 * Constants:
48 * The hexadecimal values are the intended ones for the following
49 * constants. The decimal values may be used, provided that the
50 * compiler will convert from decimal to binary accurately enough
51 * to produce the hexadecimal values shown.
52 */
53
54static const int init_jk[] = {2,3,4,6}; /* initial value for jk */
55
56static const double PIo2[] = {
57 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
58 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
59 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
60 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
61 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
62 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
63 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
64 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
65};
66
67static const double
68zero = 0.0,
69one = 1.0,
70two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
71twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
72
73/**
74 * @brief Kernel reduction function.
75 * @version 1.4
76 * @date 96/03/07
77 * @details
78 * <pre>
79 * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
80 * double x[],y[]; int e0,nx,prec; int ipio2[];
81 *
82 * __kernel_rem_pio2 return the last three digits of N with
83 * y = x - N*pi/2
84 * so that |y| < pi/2.
85 *
86 * The method is to compute the integer (mod 8) and fraction parts of
87 * (2/pi)*x without doing the full multiplication. In general we
88 * skip the part of the product that are known to be a huge integer (
89 * more accurately, = 0 mod 8 ). Thus the number of operations are
90 * independent of the exponent of the input.
91 *
92 * (2/pi) is represented by an array of 24-bit integers in ipio2[].
93 *
94 * Input parameters:
95 * x[] The input value (must be positive) is broken into nx
96 * pieces of 24-bit integers in double precision format.
97 * x[i] will be the i-th 24 bit of x. The scaled exponent
98 * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
99 * match x's up to 24 bits.
100 *
101 * Example of breaking a double positive z into x[0]+x[1]+x[2]:
102 * e0 = ilogb(z)-23
103 * z = scalbn(z,-e0)
104 * for i = 0,1,2
105 * x[i] = floor(z)
106 * z = (z-x[i])*2**24
107 *
108 *
109 * y[] ouput result in an array of double precision numbers.
110 * The dimension of y[] is:
111 * 24-bit precision 1
112 * 53-bit precision 2
113 * 64-bit precision 2
114 * 113-bit precision 3
115 * The actual value is the sum of them. Thus for 113-bit
116 * precison, one may have to do something like:
117 *
118 * long double t,w,r_head, r_tail;
119 * t = (long double)y[2] + (long double)y[1];
120 * w = (long double)y[0];
121 * r_head = t+w;
122 * r_tail = w - (r_head - t);
123 *
124 * e0 The exponent of x[0]
125 *
126 * nx dimension of x[]
127 *
128 * prec an integer indicating the precision:
129 * 0 24 bits (single)
130 * 1 53 bits (double)
131 * 2 64 bits (extended)
132 * 3 113 bits (quad)
133 *
134 * ipio2[]
135 * integer array, contains the (24*i)-th to (24*i+23)-th
136 * bit of 2/pi after binary point. The corresponding
137 * floating value is
138 *
139 * ipio2[i] * 2^(-24(i+1)).
140 *
141 * External function:
142 * double scalbn(), floor();
143 *
144 *
145 * Here is the description of some local variables:
146 *
147 * jk jk+1 is the initial number of terms of ipio2[] needed
148 * in the computation. The recommended value is 2,3,4,
149 * 6 for single, double, extended,and quad.
150 *
151 * jz local integer variable indicating the number of
152 * terms of ipio2[] used.
153 *
154 * jx nx - 1
155 *
156 * jv index for pointing to the suitable ipio2[] for the
157 * computation. In general, we want
158 * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
159 * is an integer. Thus
160 * e0-3-24*jv >= 0 or (e0-3)/24 >= jv
161 * Hence jv = max(0,(e0-3)/24).
162 *
163 * jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
164 *
165 * q[] double array with integral value, representing the
166 * 24-bits chunk of the product of x and 2/pi.
167 *
168 * q0 the corresponding exponent of q[0]. Note that the
169 * exponent for q[i] would be q0-24*i.
170 *
171 * PIo2[] double precision array, obtained by cutting pi/2
172 * into 24 bits chunks.
173 *
174 * f[] ipio2[] in floating point
175 *
176 * iq[] integer array by breaking up q[] in 24-bits chunk.
177 *
178 * fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
179 *
180 * ih integer. If >0 it indicates q[] is >= 0.5, hence
181 * it also indicates the *sign* of the result.
182 *
183 * </pre>
184 * @copyright Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
185 * @license Developed at SunSoft, a Sun Microsystems, Inc. business. Permission
186 * to use, copy, modify, and distribute this software is freely granted,
187 * provided that this notice is preserved.
188 */
189
190int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int *ipio2)
191{
192 int jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
193 double z,fw,f[20],fq[20],q[20];
194
195 /* initialize jk*/
196 jk = init_jk[prec];
197 jp = jk;
198
199 /* determine jx,jv,q0, note that 3>q0 */
200 jx = nx-1;
201 jv = (e0-3)/24;
202 if(jv<0) jv=0;
1
Assuming 'jv' is >= 0
2
Taking false branch
203 q0 = e0-24*(jv+1);
204
205 /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
206 j = jv-jx;
207 m = jx+jk;
208 for(i=0; i<=m; i++,j++) f[i] = (j<0)? zero : (double) ipio2[j];
3
Assuming 'i' is > 'm'
4
Loop condition is false. Execution continues on line 211
209
210 /* compute q[0],q[1],...q[jk] */
211 for (i=0; i<=jk; i++) {
5
Assuming 'i' is > 'jk'
6
Loop condition is false. Execution continues on line 216
212 for(j=0,fw=0.0; j<=jx; j++) fw += x[j]*f[jx+i-j];
213 q[i] = fw;
214 }
215
216 jz = jk;
217recompute:
218 /* distill q[] into iq[] reversingly */
219 for(i=0,j=jz,z=q[jz]; j>0; i++,j--) {
7
Loop condition is false. Execution continues on line 226
220 fw = (double)((int)(twon24* z));
221 iq[i] = (int)(z-two24*fw);
222 z = q[j-1]+fw;
223 }
224
225 /* compute n */
226 z = scalbn(z,q0); /* actual value of z */
227 z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */
228 n = (int) z;
229 z -= (double)n;
230 ih = 0;
231 if(q0>0) { /* need iq[jz-1] to determine n */
8
Assuming 'q0' is <= 0
9
Taking false branch
232 i = (iq[jz-1]>>(24-q0));
233 n += i;
234 iq[jz-1] -= i<<(24-q0);
235 ih = iq[jz-1]>>(23-q0);
236 }
237 else if(q0==0) ih = iq[jz-1]>>23;
10
Assuming 'q0' is not equal to 0
11
Taking false branch
238 else if(z>=0.5) ih=2;
12
Taking false branch
239
240 if(ih>0) { /* q > 0.5 */
13
Taking false branch
241 n += 1;
242 carry = 0;
243 for(i=0; i<jz ; i++) { /* compute 1-q */
244 j = iq[i];
245 if(carry==0) {
246 if(j!=0) {
247 carry = 1;
248 iq[i] = 0x1000000- j;
249 }
250 } else iq[i] = 0xffffff - j;
251 }
252 if(q0>0) { /* rare case: chance is 1 in 12 */
253 switch(q0) {
254 case 1:
255 iq[jz-1] &= 0x7fffff;
256 break;
257 case 2:
258 iq[jz-1] &= 0x3fffff;
259 break;
260 }
261 }
262 if(ih==2) {
263 z = one - z;
264 if(carry!=0) z -= scalbn(one,q0);
265 }
266 }
267
268 /* check if recomputation is needed */
269 if(z==zero) {
14
Taking false branch
270 j = 0;
271 for (i=jz-1; i>=jk; i--) j |= iq[i];
272 if(j==0) { /* need recomputation */
273 for(k=1; iq[jk-k]==0; k++); /* k = no. of terms needed */
274
275 for(i=jz+1; i<=jz+k; i++) { /* add q[jz+1] to q[jz+k] */
276 f[jx+i] = (double) ipio2[jv+i];
277 for(j=0,fw=0.0; j<=jx; j++) fw += x[j]*f[jx+i-j];
278 q[i] = fw;
279 }
280 jz += k;
281 goto recompute;
282 }
283 }
284
285 /* chop off zero terms */
286 if(z==0.0) {
15
Taking false branch
287 jz -= 1;
288 q0 -= 24;
289 while(iq[jz]==0) {
290 jz--;
291 q0-=24;
292 }
293 } else { /* break z into 24-bit if necessary */
294 z = scalbn(z,-q0);
295 if(z>=two24) {
16
Taking true branch
296 fw = (double)((int)(twon24*z));
297 iq[jz] = (int)(z-two24*fw);
298 jz += 1;
299 q0 += 24;
300 iq[jz] = (int) fw;
301 } else iq[jz] = (int) z ;
302 }
303
304 /* convert integer "bit" chunk to floating-point value */
305 fw = scalbn(one,q0);
306 for(i=jz; i>=0; i--) {
17
Assuming 'i' is >= 0
18
Loop condition is true. Entering loop body
19
Loop condition is false. Execution continues on line 312
307 q[i] = fw*(double)iq[i];
308 fw*=twon24;
309 }
310
311 /* compute PIo2[0,...,jp]*q[jz,...,0] */
312 for(i=jz; i>=0; i--) {
20
Loop condition is true. Entering loop body
21
Loop condition is false. Execution continues on line 318
313 for(fw=0.0,k=0; k<=jp&&k<=jz-i; k++) fw += PIo2[k]*q[i+k];
314 fq[jz-i] = fw;
315 }
316
317 /* compress fq[] into y[] */
318 switch(prec) {
22
Control jumps to 'case 3:' at line 333
319 case 0:
320 fw = 0.0;
321 for (i=jz; i>=0; i--) fw += fq[i];
322 y[0] = (ih==0)? fw: -fw;
323 break;
324 case 1:
325 case 2:
326 fw = 0.0;
327 for (i=jz; i>=0; i--) fw += fq[i];
328 y[0] = (ih==0)? fw: -fw;
329 fw = fq[0]-fw;
330 for (i=1; i<=jz; i++) fw += fq[i];
331 y[1] = (ih==0)? fw: -fw;
332 break;
333 case 3: /* painful */
334 for (i=jz; i>0; i--) {
23
Loop condition is false. Execution continues on line 339
335 fw = fq[i-1]+fq[i];
336 fq[i] += fq[i-1]-fw;
337 fq[i-1] = fw;
338 }
339 for (i=jz; i>1; i--) {
24
Loop condition is false. Execution continues on line 344
340 fw = fq[i-1]+fq[i];
341 fq[i] += fq[i-1]-fw;
342 fq[i-1] = fw;
343 }
344 for (fw=0.0,i=jz; i>=2; i--) fw += fq[i];
25
Loop condition is false. Execution continues on line 345
345 if(ih==0) {
26
Taking true branch
346 y[0] = fq[0];
347 y[1] = fq[1];
27
Assigned value is garbage or undefined
348 y[2] = fw;
349 } else {
350 y[0] = -fq[0];
351 y[1] = -fq[1];
352 y[2] = -fw;
353 }
354 }
355 return n&7;
356}
diff --git a/scan-build/report-fcf014.html b/scan-build/report-fcf014.html deleted file mode 100644 index 262651a9..00000000 --- a/scan-build/report-fcf014.html +++ /dev/null @@ -1,477 +0,0 @@ - - - -lib/real/kremp2.c - - - - - - - - - - - - - - - - - - - - - - - - - -

Bug Summary

- - - - -
File:real/kremp2.c
Location:line 271, column 36
Description:Assigned value is garbage or undefined
- -

Annotated Source Code

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1/* @(#)k_rem_pio2.c 1.3 95/01/18 */
2
3/*
4 * Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * The origin source code can be obtained from:
28 * http://www.netlib.org/fdlibm/k_rem_pio2.c
29 *
30 */
31
32/*
33 * ====================================================
34 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
35 *
36 * Developed at SunSoft, a Sun Microsystems, Inc. business.
37 * Permission to use, copy, modify, and distribute this
38 * software is freely granted, provided that this notice
39 * is preserved.
40 * ====================================================
41 */
42
43#include "prim.h"
44#include "math.h"
45
46/*
47 * Constants:
48 * The hexadecimal values are the intended ones for the following
49 * constants. The decimal values may be used, provided that the
50 * compiler will convert from decimal to binary accurately enough
51 * to produce the hexadecimal values shown.
52 */
53
54static const int init_jk[] = {2,3,4,6}; /* initial value for jk */
55
56static const double PIo2[] = {
57 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
58 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
59 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
60 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
61 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
62 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
63 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
64 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
65};
66
67static const double
68zero = 0.0,
69one = 1.0,
70two24 = 1.67772160000000000000e+07, /* 0x41700000, 0x00000000 */
71twon24 = 5.96046447753906250000e-08; /* 0x3E700000, 0x00000000 */
72
73/**
74 * @brief Kernel reduction function.
75 * @version 1.4
76 * @date 96/03/07
77 * @details
78 * <pre>
79 * __kernel_rem_pio2(x,y,e0,nx,prec,ipio2)
80 * double x[],y[]; int e0,nx,prec; int ipio2[];
81 *
82 * __kernel_rem_pio2 return the last three digits of N with
83 * y = x - N*pi/2
84 * so that |y| < pi/2.
85 *
86 * The method is to compute the integer (mod 8) and fraction parts of
87 * (2/pi)*x without doing the full multiplication. In general we
88 * skip the part of the product that are known to be a huge integer (
89 * more accurately, = 0 mod 8 ). Thus the number of operations are
90 * independent of the exponent of the input.
91 *
92 * (2/pi) is represented by an array of 24-bit integers in ipio2[].
93 *
94 * Input parameters:
95 * x[] The input value (must be positive) is broken into nx
96 * pieces of 24-bit integers in double precision format.
97 * x[i] will be the i-th 24 bit of x. The scaled exponent
98 * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
99 * match x's up to 24 bits.
100 *
101 * Example of breaking a double positive z into x[0]+x[1]+x[2]:
102 * e0 = ilogb(z)-23
103 * z = scalbn(z,-e0)
104 * for i = 0,1,2
105 * x[i] = floor(z)
106 * z = (z-x[i])*2**24
107 *
108 *
109 * y[] ouput result in an array of double precision numbers.
110 * The dimension of y[] is:
111 * 24-bit precision 1
112 * 53-bit precision 2
113 * 64-bit precision 2
114 * 113-bit precision 3
115 * The actual value is the sum of them. Thus for 113-bit
116 * precison, one may have to do something like:
117 *
118 * long double t,w,r_head, r_tail;
119 * t = (long double)y[2] + (long double)y[1];
120 * w = (long double)y[0];
121 * r_head = t+w;
122 * r_tail = w - (r_head - t);
123 *
124 * e0 The exponent of x[0]
125 *
126 * nx dimension of x[]
127 *
128 * prec an integer indicating the precision:
129 * 0 24 bits (single)
130 * 1 53 bits (double)
131 * 2 64 bits (extended)
132 * 3 113 bits (quad)
133 *
134 * ipio2[]
135 * integer array, contains the (24*i)-th to (24*i+23)-th
136 * bit of 2/pi after binary point. The corresponding
137 * floating value is
138 *
139 * ipio2[i] * 2^(-24(i+1)).
140 *
141 * External function:
142 * double scalbn(), floor();
143 *
144 *
145 * Here is the description of some local variables:
146 *
147 * jk jk+1 is the initial number of terms of ipio2[] needed
148 * in the computation. The recommended value is 2,3,4,
149 * 6 for single, double, extended,and quad.
150 *
151 * jz local integer variable indicating the number of
152 * terms of ipio2[] used.
153 *
154 * jx nx - 1
155 *
156 * jv index for pointing to the suitable ipio2[] for the
157 * computation. In general, we want
158 * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
159 * is an integer. Thus
160 * e0-3-24*jv >= 0 or (e0-3)/24 >= jv
161 * Hence jv = max(0,(e0-3)/24).
162 *
163 * jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
164 *
165 * q[] double array with integral value, representing the
166 * 24-bits chunk of the product of x and 2/pi.
167 *
168 * q0 the corresponding exponent of q[0]. Note that the
169 * exponent for q[i] would be q0-24*i.
170 *
171 * PIo2[] double precision array, obtained by cutting pi/2
172 * into 24 bits chunks.
173 *
174 * f[] ipio2[] in floating point
175 *
176 * iq[] integer array by breaking up q[] in 24-bits chunk.
177 *
178 * fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
179 *
180 * ih integer. If >0 it indicates q[] is >= 0.5, hence
181 * it also indicates the *sign* of the result.
182 *
183 * </pre>
184 * @copyright Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
185 * @license Developed at SunSoft, a Sun Microsystems, Inc. business. Permission
186 * to use, copy, modify, and distribute this software is freely granted,
187 * provided that this notice is preserved.
188 */
189
190int __kernel_rem_pio2(double *x, double *y, int e0, int nx, int prec, const int *ipio2)
191{
192 int jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
193 double z,fw,f[20],fq[20],q[20];
194
195 /* initialize jk*/
196 jk = init_jk[prec];
197 jp = jk;
198
199 /* determine jx,jv,q0, note that 3>q0 */
200 jx = nx-1;
201 jv = (e0-3)/24;
202 if(jv<0) jv=0;
1
Assuming 'jv' is >= 0
2
Taking false branch
203 q0 = e0-24*(jv+1);
204
205 /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
206 j = jv-jx;
207 m = jx+jk;
208 for(i=0; i<=m; i++,j++) f[i] = (j<0)? zero : (double) ipio2[j];
3
Assuming 'i' is > 'm'
4
Loop condition is false. Execution continues on line 211
209
210 /* compute q[0],q[1],...q[jk] */
211 for (i=0; i<=jk; i++) {
5
Assuming 'i' is > 'jk'
6
Loop condition is false. Execution continues on line 216
212 for(j=0,fw=0.0; j<=jx; j++) fw += x[j]*f[jx+i-j];
213 q[i] = fw;
214 }
215
216 jz = jk;
217recompute:
218 /* distill q[] into iq[] reversingly */
219 for(i=0,j=jz,z=q[jz]; j>0; i++,j--) {
7
Loop condition is false. Execution continues on line 226
22
Assuming 'j' is > 0
23
Loop condition is true. Entering loop body
24
Assuming 'j' is <= 0
25
Loop condition is false. Execution continues on line 226
220 fw = (double)((int)(twon24* z));
221 iq[i] = (int)(z-two24*fw);
222 z = q[j-1]+fw;
223 }
224
225 /* compute n */
226 z = scalbn(z,q0); /* actual value of z */
227 z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */
228 n = (int) z;
229 z -= (double)n;
230 ih = 0;
231 if(q0>0) { /* need iq[jz-1] to determine n */
8
Assuming 'q0' is <= 0
9
Taking false branch
26
Taking false branch
232 i = (iq[jz-1]>>(24-q0));
233 n += i;
234 iq[jz-1] -= i<<(24-q0);
235 ih = iq[jz-1]>>(23-q0);
236 }
237 else if(q0==0) ih = iq[jz-1]>>23;
10
Assuming 'q0' is not equal to 0
11
Taking false branch
27
Taking false branch
238 else if(z>=0.5) ih=2;
12
Taking false branch
28
Taking false branch
239
240 if(ih>0) { /* q > 0.5 */
13
Taking false branch
29
Taking false branch
241 n += 1;
242 carry = 0;
243 for(i=0; i<jz ; i++) { /* compute 1-q */
244 j = iq[i];
245 if(carry==0) {
246 if(j!=0) {
247 carry = 1;
248 iq[i] = 0x1000000- j;
249 }
250 } else iq[i] = 0xffffff - j;
251 }
252 if(q0>0) { /* rare case: chance is 1 in 12 */
253 switch(q0) {
254 case 1:
255 iq[jz-1] &= 0x7fffff;
256 break;
257 case 2:
258 iq[jz-1] &= 0x3fffff;
259 break;
260 }
261 }
262 if(ih==2) {
263 z = one - z;
264 if(carry!=0) z -= scalbn(one,q0);
265 }
266 }
267
268 /* check if recomputation is needed */
269 if(z==zero) {
14
Taking true branch
30
Taking true branch
270 j = 0;
271 for (i=jz-1; i>=jk; i--) j |= iq[i];
15
Loop condition is false. Execution continues on line 272
31
Loop condition is true. Entering loop body
32
Loop condition is true. Entering loop body
33
Assigned value is garbage or undefined
272 if(j==0) { /* need recomputation */
16
Taking true branch
273 for(k=1; iq[jk-k]==0; k++); /* k = no. of terms needed */
17
Loop condition is true. Entering loop body
18
Loop condition is true. Entering loop body
19
Loop condition is false. Execution continues on line 275
274
275 for(i=jz+1; i<=jz+k; i++) { /* add q[jz+1] to q[jz+k] */
20
Loop condition is false. Execution continues on line 280
276 f[jx+i] = (double) ipio2[jv+i];
277 for(j=0,fw=0.0; j<=jx; j++) fw += x[j]*f[jx+i-j];
278 q[i] = fw;
279 }
280 jz += k;
281 goto recompute;
21
Control jumps to line 219
282 }
283 }
284
285 /* chop off zero terms */
286 if(z==0.0) {
287 jz -= 1;
288 q0 -= 24;
289 while(iq[jz]==0) {
290 jz--;
291 q0-=24;
292 }
293 } else { /* break z into 24-bit if necessary */
294 z = scalbn(z,-q0);
295 if(z>=two24) {
296 fw = (double)((int)(twon24*z));
297 iq[jz] = (int)(z-two24*fw);
298 jz += 1;
299 q0 += 24;
300 iq[jz] = (int) fw;
301 } else iq[jz] = (int) z ;
302 }
303
304 /* convert integer "bit" chunk to floating-point value */
305 fw = scalbn(one,q0);
306 for(i=jz; i>=0; i--) {
307 q[i] = fw*(double)iq[i];
308 fw*=twon24;
309 }
310
311 /* compute PIo2[0,...,jp]*q[jz,...,0] */
312 for(i=jz; i>=0; i--) {
313 for(fw=0.0,k=0; k<=jp&&k<=jz-i; k++) fw += PIo2[k]*q[i+k];
314 fq[jz-i] = fw;
315 }
316
317 /* compress fq[] into y[] */
318 switch(prec) {
319 case 0:
320 fw = 0.0;
321 for (i=jz; i>=0; i--) fw += fq[i];
322 y[0] = (ih==0)? fw: -fw;
323 break;
324 case 1:
325 case 2:
326 fw = 0.0;
327 for (i=jz; i>=0; i--) fw += fq[i];
328 y[0] = (ih==0)? fw: -fw;
329 fw = fq[0]-fw;
330 for (i=1; i<=jz; i++) fw += fq[i];
331 y[1] = (ih==0)? fw: -fw;
332 break;
333 case 3: /* painful */
334 for (i=jz; i>0; i--) {
335 fw = fq[i-1]+fq[i];
336 fq[i] += fq[i-1]-fw;
337 fq[i-1] = fw;
338 }
339 for (i=jz; i>1; i--) {
340 fw = fq[i-1]+fq[i];
341 fq[i] += fq[i-1]-fw;
342 fq[i-1] = fw;
343 }
344 for (fw=0.0,i=jz; i>=2; i--) fw += fq[i];
345 if(ih==0) {
346 y[0] = fq[0];
347 y[1] = fq[1];
348 y[2] = fw;
349 } else {
350 y[0] = -fq[0];
351 y[1] = -fq[1];
352 y[2] = -fw;
353 }
354 }
355 return n&7;
356}
diff --git a/scan-build/scanview.css b/scan-build/scanview.css deleted file mode 100644 index cf8a5a6a..00000000 --- a/scan-build/scanview.css +++ /dev/null @@ -1,62 +0,0 @@ -body { color:#000000; background-color:#ffffff } -body { font-family: Helvetica, sans-serif; font-size:9pt } -h1 { font-size: 14pt; } -h2 { font-size: 12pt; } -table { font-size:9pt } -table { border-spacing: 0px; border: 1px solid black } -th, table thead { - background-color:#eee; color:#666666; - font-weight: bold; cursor: default; - text-align:center; - font-weight: bold; font-family: Verdana; - white-space:nowrap; -} -.W { font-size:0px } -th, td { padding:5px; padding-left:8px; text-align:left } -td.SUMM_DESC { padding-left:12px } -td.DESC { white-space:pre } -td.Q { text-align:right } -td { text-align:left } -tbody.scrollContent { overflow:auto } - -table.form_group { - background-color: #ccc; - border: 1px solid #333; - padding: 2px; -} - -table.form_inner_group { - background-color: #ccc; - border: 1px solid #333; - padding: 0px; -} - -table.form { - background-color: #999; - border: 1px solid #333; - padding: 2px; -} - -td.form_label { - text-align: right; - vertical-align: top; -} -/* For one line entires */ -td.form_clabel { - text-align: right; - vertical-align: center; -} -td.form_value { - text-align: left; - vertical-align: top; -} -td.form_submit { - text-align: right; - vertical-align: top; -} - -h1.SubmitFail { - color: #f00; -} -h1.SubmitOk { -} diff --git a/scan-build/sorttable.js b/scan-build/sorttable.js deleted file mode 100644 index 32faa078..00000000 --- a/scan-build/sorttable.js +++ /dev/null @@ -1,492 +0,0 @@ -/* - SortTable - version 2 - 7th April 2007 - Stuart Langridge, http://www.kryogenix.org/code/browser/sorttable/ - - Instructions: - Download this file - Add to your HTML - Add class="sortable" to any table you'd like to make sortable - Click on the headers to sort - - Thanks to many, many people for contributions and suggestions. - Licenced as X11: http://www.kryogenix.org/code/browser/licence.html - This basically means: do what you want with it. -*/ - - -var stIsIE = /*@cc_on!@*/false; - -sorttable = { - init: function() { - // quit if this function has already been called - if (arguments.callee.done) return; - // flag this function so we don't do the same thing twice - arguments.callee.done = true; - // kill the timer - if (_timer) clearInterval(_timer); - - if (!document.createElement || !document.getElementsByTagName) return; - - sorttable.DATE_RE = /^(\d\d?)[\/\.-](\d\d?)[\/\.-]((\d\d)?\d\d)$/; - - forEach(document.getElementsByTagName('table'), function(table) { - if (table.className.search(/\bsortable\b/) != -1) { - sorttable.makeSortable(table); - } - }); - - }, - - makeSortable: function(table) { - if (table.getElementsByTagName('thead').length == 0) { - // table doesn't have a tHead. Since it should have, create one and - // put the first table row in it. - the = document.createElement('thead'); - the.appendChild(table.rows[0]); - table.insertBefore(the,table.firstChild); - } - // Safari doesn't support table.tHead, sigh - if (table.tHead == null) table.tHead = table.getElementsByTagName('thead')[0]; - - if (table.tHead.rows.length != 1) return; // can't cope with two header rows - - // Sorttable v1 put rows with a class of "sortbottom" at the bottom (as - // "total" rows, for example). This is B&R, since what you're supposed - // to do is put them in a tfoot. So, if there are sortbottom rows, - // for backward compatibility, move them to tfoot (creating it if needed). - sortbottomrows = []; - for (var i=0; i5' : ' ▴'; - this.appendChild(sortrevind); - return; - } - if (this.className.search(/\bsorttable_sorted_reverse\b/) != -1) { - // if we're already sorted by this column in reverse, just - // re-reverse the table, which is quicker - sorttable.reverse(this.sorttable_tbody); - this.className = this.className.replace('sorttable_sorted_reverse', - 'sorttable_sorted'); - this.removeChild(document.getElementById('sorttable_sortrevind')); - sortfwdind = document.createElement('span'); - sortfwdind.id = "sorttable_sortfwdind"; - sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; - this.appendChild(sortfwdind); - return; - } - - // remove sorttable_sorted classes - theadrow = this.parentNode; - forEach(theadrow.childNodes, function(cell) { - if (cell.nodeType == 1) { // an element - cell.className = cell.className.replace('sorttable_sorted_reverse',''); - cell.className = cell.className.replace('sorttable_sorted',''); - } - }); - sortfwdind = document.getElementById('sorttable_sortfwdind'); - if (sortfwdind) { sortfwdind.parentNode.removeChild(sortfwdind); } - sortrevind = document.getElementById('sorttable_sortrevind'); - if (sortrevind) { sortrevind.parentNode.removeChild(sortrevind); } - - this.className += ' sorttable_sorted'; - sortfwdind = document.createElement('span'); - sortfwdind.id = "sorttable_sortfwdind"; - sortfwdind.innerHTML = stIsIE ? ' 6' : ' ▾'; - this.appendChild(sortfwdind); - - // build an array to sort. This is a Schwartzian transform thing, - // i.e., we "decorate" each row with the actual sort key, - // sort based on the sort keys, and then put the rows back in order - // which is a lot faster because you only do getInnerText once per row - row_array = []; - col = this.sorttable_columnindex; - rows = this.sorttable_tbody.rows; - for (var j=0; j 12) { - // definitely dd/mm - return sorttable.sort_ddmm; - } else if (second > 12) { - return sorttable.sort_mmdd; - } else { - // looks like a date, but we can't tell which, so assume - // that it's dd/mm (English imperialism!) and keep looking - sortfn = sorttable.sort_ddmm; - } - } - } - } - return sortfn; - }, - - getInnerText: function(node) { - // gets the text we want to use for sorting for a cell. - // strips leading and trailing whitespace. - // this is *not* a generic getInnerText function; it's special to sorttable. - // for example, you can override the cell text with a customkey attribute. - // it also gets .value for fields. - - hasInputs = (typeof node.getElementsByTagName == 'function') && - node.getElementsByTagName('input').length; - - if (node.getAttribute("sorttable_customkey") != null) { - return node.getAttribute("sorttable_customkey"); - } - else if (typeof node.textContent != 'undefined' && !hasInputs) { - return node.textContent.replace(/^\s+|\s+$/g, ''); - } - else if (typeof node.innerText != 'undefined' && !hasInputs) { - return node.innerText.replace(/^\s+|\s+$/g, ''); - } - else if (typeof node.text != 'undefined' && !hasInputs) { - return node.text.replace(/^\s+|\s+$/g, ''); - } - else { - switch (node.nodeType) { - case 3: - if (node.nodeName.toLowerCase() == 'input') { - return node.value.replace(/^\s+|\s+$/g, ''); - } - case 4: - return node.nodeValue.replace(/^\s+|\s+$/g, ''); - break; - case 1: - case 11: - var innerText = ''; - for (var i = 0; i < node.childNodes.length; i++) { - innerText += sorttable.getInnerText(node.childNodes[i]); - } - return innerText.replace(/^\s+|\s+$/g, ''); - break; - default: - return ''; - } - } - }, - - reverse: function(tbody) { - // reverse the rows in a tbody - newrows = []; - for (var i=0; i=0; i--) { - tbody.appendChild(newrows[i]); - } - delete newrows; - }, - - /* sort functions - each sort function takes two parameters, a and b - you are comparing a[0] and b[0] */ - sort_numeric: function(a,b) { - aa = parseFloat(a[0].replace(/[^0-9.-]/g,'')); - if (isNaN(aa)) aa = 0; - bb = parseFloat(b[0].replace(/[^0-9.-]/g,'')); - if (isNaN(bb)) bb = 0; - return aa-bb; - }, - sort_alpha: function(a,b) { - if (a[0]==b[0]) return 0; - if (a[0] 0 ) { - var q = list[i]; list[i] = list[i+1]; list[i+1] = q; - swap = true; - } - } // for - t--; - - if (!swap) break; - - for(var i = t; i > b; --i) { - if ( comp_func(list[i], list[i-1]) < 0 ) { - var q = list[i]; list[i] = list[i-1]; list[i-1] = q; - swap = true; - } - } // for - b++; - - } // while(swap) - } -} - -/* ****************************************************************** - Supporting functions: bundled here to avoid depending on a library - ****************************************************************** */ - -// Dean Edwards/Matthias Miller/John Resig - -/* for Mozilla/Opera9 */ -if (document.addEventListener) { - document.addEventListener("DOMContentLoaded", sorttable.init, false); -} - -/* for Internet Explorer */ -/*@cc_on @*/ -/*@if (@_win32) - document.write("