Merge branch 'sqrt_decn'

This commit is contained in:
Jeff Wang 2020-09-13 23:00:56 -04:00
commit 233f347ecc
9 changed files with 220 additions and 451 deletions

View File

@ -109,7 +109,7 @@ Press `Shift` (the `mode` key on the physical calculator) and then `0` to turn o
# Building # Building
There is a prebuilt binary for the calculator checked in at `binaries/main.hex` for the calculator. Building is fairly straigtforward though. Github releases has prebuilt binaries for the calculator. Building is fairly straigtforward though.
- Use the Makefile for building a new firmware for the calculator. - Use the Makefile for building a new firmware for the calculator.
- type `make` to build - type `make` to build
@ -206,7 +206,7 @@ I sometimes use an STC15F2K60S2 for development work. This microcontroller is av
## Programming with stcgal ## Programming with stcgal
Run `stcgal` as shown below, replacing `stc_rpncalc/main.hex` with the actual path to the main.hex you built. There are also prebuilt binaries in the `binaries` directory. In this example, I'm programming at a relatively high line rate of 230,400 bits/s. This works very reliably, but you may want to try at a slower speed to start (omit the `-b 230400` option). Run `stcgal` as shown below, replacing `stc_rpncalc/main.hex` with the actual path to the main.hex you built. There are also prebuilt binaries in the `binaries` directory. In this example, I'm programming at a relatively high line rate of 230,400 bits/s. This works very reliably, but you may want to try at a slower speed to start (omit the `-b 230400` option), especially when using an inline resistor and diode.
~~~~ ~~~~
$ ./stcgal.py -P stc15 -b 230400 stc_rpncalc/main.hex $ ./stcgal.py -P stc15 -b 230400 stc_rpncalc/main.hex
@ -251,7 +251,7 @@ Disconnected!
# Bugs # Bugs
1. After division by 0, ln(-), over/underflow, or other operations which give an `Error`, it's possible to still do certain operations on `Error`. Many functions do check, and will not operate on `Error`, but not all of them yet. This is somewhat similar to old soviet Elektronika calculators where `Error` is just a number, and there wasn't enough ROM space to check for errors. (There are people who explore the inner-workings of these calculators by manipulating the `Error` "number".) 1. After division by 0, ln(-), over/underflow, or other operations which give an `Error`, it's possible to still do certain operations on `Error`. Many functions do check, and will not operate on `Error`, but not all of them yet. This is somewhat similar to old soviet Elektronika calculators where `Error` is just a number, and there wasn't enough ROM space to check for errors. (There are people who explore the inner-workings of these calculators by manipulating the `Error` "number".)
1. When shifted down, keys which do not have a shifted-down function will instead be interpreted as if there were no shift. 1. When shifted, keys which do not have a shifted function will instead be interpreted as if there were no shift.
1. Trigonometric functions are extremely slow and inaccurate. 1. Trigonometric functions are extremely slow and inaccurate.
1. There are probably more bugs waiting to be discovered. 1. There are probably more bugs waiting to be discovered.
@ -300,7 +300,9 @@ The number `0.135` would be stored the same way, except now the exponent is `0x7
- Exponentials are calculated similar to the HP 35 algorithm, as described [here](http://www.jacques-laporte.org/expx.htm) using the same constants as the logarithm algorithm. - Exponentials are calculated similar to the HP 35 algorithm, as described [here](http://www.jacques-laporte.org/expx.htm) using the same constants as the logarithm algorithm.
- see `src/decn/proto/exp.cpp` for initial prototyping development work - see `src/decn/proto/exp.cpp` for initial prototyping development work
- Powers are calculated using the identity y^x = e^(x*ln(y)) - Powers are calculated using the identity y^x = e^(x*ln(y))
- Square roots are calculated using the identity sqrt(x) = e^(0.5*ln(x)) - Square roots are calculated using a fixed number of Newton-Raphson iterations to calculatie 1/sqrt(x) and then multiplying by x.
- the iteration for 1/sqrt(x) is new_estimate = 0.5*estimate * (3 - x * estimate * estimate)
- see `src/decn/proto/recip_sqrt.cpp for initial prototyping development work
- Trigonometric functions are calculated using algorithms similar to the [sinclair scientific](http://files.righto.com/calculator/sinclair_scientific_simulator.html), and are fairly slow and inaccurate. - Trigonometric functions are calculated using algorithms similar to the [sinclair scientific](http://files.righto.com/calculator/sinclair_scientific_simulator.html), and are fairly slow and inaccurate.
## TODO ## TODO

View File

@ -1,391 +0,0 @@
:0400000002001332B5
:03000B0002008967
:09006C00751600751701751800E6
:0300860002000E67
:03000E0002017874
:20008900C021C0E0C0F0C082C083C0D075D008120B22120BEC74FFB52202801A200007E58A
:2000A90015B514028020E5142410F8A622E514045403F514C2007880860FBF0809788486CC
:2000C9000FBF0802C2B2D0D0D083D082D0F0D0E0D02132438E80758AC5758C1DC28DD28C13
:2000E900D2A9D2AF22AFB174FB5FF5B143B204D2B222C374019517E433FFB40100E433F5AB
:200109008222751600751800900012E4F0900013F022C374019517B3E433FF7040900013EF
:20012900E075F00AA4FF900012E0FE2FFF7405B51704C3E49FFFE5162401F582E43400F5E4
:2001490083E4F09000A0EFF0EF3395E0A3F09000011225EF12010BE56360020563E5199091
:200169002DEB93F58212282F75170175630022D2001200EE1208FD120AD21200DCC2B49099
:200189000012E4F0900013F0902DFF120A2078808607BF080978848607BF0802C2B22000AA
:2001A900EDE5152410F98719E515045403F515E514B51502D200E519902DEB93FFBF2A0368
:2001C9000205A0BF2B030205A0BF2D030205A0BF2E030203A6BF2F030205A0BF3002805150
:2001E900BF31030202B6BF32030202B6BF33030202B6BF34030202B6BF35030202B6BF3696
:20020900030202B6BF37030202B6BF38030202B6BF39030202B6BF3C030205A0BF3D030256
:20022900047DBF630302053EBF72030205A00205FE300205C2B202060374FC2517502EE525
:2002490018700B900012E4F0751801020603900012E0FE900013F0900012E4F00518E51850
:2002690024FD4003020603751801020603C374019517B3E433FE6013751702E5162401F5AB
:2002890082E43400F583EFF0020603E516700302060374F025165003020603E5162401F5CE
:2002A90082E43400F583EFF0051602060330025FC374019517B3E433FE7040900013E07539
:2002C900F00AA4FE900012E0FD2EFE7405B51704C3E49EFEE5162401F582E43400F583E437
:2002E900F09000A0EEF0EE3395E0A3F09000011225EF12010BE56360020563E519902DEB41
:2003090093F58212282F75170175630002060374FC2517503DE5187013E519902DEB9324DB
:20032900D0FE900012F0751801020603900012E0900013F0E519902DEB9324D0FE900012D9
:20034900F00518E51824FD4003020603751801020603C374019517B3E433FE601D751702CB
:20036900E5162401FDE43400FEE519902DEB93FC8D828E83F0051602060374F025165003E4
:20038900020603E5162401FDE43400FEE519902DEB93FC8D828E83F0051602060330025F1A
:2003A900C374019517B3E433FE7040900013E075F00AA4FE900012E0FD2EFE7405B5170450
:2003C900C3E49EFEE5162401F582E43400F583E4F09000A0EEF0EE3395E0A3F090000112FC
:2003E90025EF12010BE56360020563E519902DEB93F58212282F751701756300020603C364
:2004090074019517B3E433FE6028AE160516EE2401F582E43400F5837430F0AE160516EE08
:200429002401F582E43400F583742EF07517030206037402B5172CE5167011AE160516EEA4
:200449002401F582E43400F5837430F0AE160516EE2401F582E43400F583742EF0751703B9
:20046900020603E51724FB4005051702060375170402060330025FC374019517B3E433FE09
:200489007040900013E075F00AA4FE900012E0FD2EFE7405B51704C3E49EFEE5162401F5C3
:2004A90082E43400F583E4F09000A0EEF0EE3395E0A3F09000011225EF12010BE563600297
:2004C9000563E519902DEB93F58212282F751701756300020603C374019517B3E433FE7006
:2004E90040900013E075F00AA4FE900012E0FD2EFE7405B51704C3E49EFEE5162401F58251
:20050900E43400F583E4F09000A0EEF0EE3395E0A3F09000011225EF12010BE563600205B3
:2005290063E519902DEB93F58212282F75170175630102060320020BC374019517B3E433EA
:20054900FE6019C20275630112010B751700E519902DEB93F58212282F02060374FC251704
:2005690050111517751800900012E4F0900013F0020603E51670030206031516E516240180
:20058900F582E43400F583E0FEBE2E028003020603751702020603C374019517B3E433FEAC
:2005A9007040900013E075F00AA4FE900012E0FD2EFE7405B51704C3E49EFEE5162401F5A2
:2005C90082E43400F583E4F09000A0EEF0EE3395E0A3F09000011225EF12010BE563600276
:2005E9000563E519902DEB93F58212282F75170175630080058F8212282F751C0075820085
:200609001209A9C374019517B3E433FF7004E5636016122661AE82AF837D008E828F838D07
:20062900F01222C7AF82801412264EAD82AE837C008D828E838CF01222C7AF82EF700B75F8
:200649001D1090001F1209EB8065751D0D90001FC0071209EBD007EF30E710758201C00703
:20066900120A42D007C3E49FFF800A758200C007120A42D007C2D575F00AEF30E704B2D5E3
:20068900F4048430D502F4042430F582C007120A42D00775F00AEFC2D530E704D2D5F40460
:2006A90084E5F030D502F4042430F582120A42758200120A937401B51702800302075312D6
:2006C900264EAD82AE837C008D828E838CF01222C7E582FF700C751D1090001F1209EB02EF
:2006E90007FD751D0D90001FC0071209EBD007EF30E710758201C007120A42D007C3E49FAB
:20070900FF800A758200C007120A42D007C2D575F00AEF30E704B2D5F4048430D502F40442
:200729002430F582C007120A42D00775F00AEFC2D530E704D2D5F40484E5F030D502F404E2
:200749002430F582120A420207FDE5167009758230120A420207FD74FC2517402A7F00C30A
:20076900EF951640030207FDBF100040030207FDEF2401F582E43400F583E0F582C007122A
:200789000A42D0070F80D87F00C3EF9516501CBF0D005017EF2401F582E43400F583E0F55B
:2007A90082C007120A42D0070F80DEBF0D005012BF0D005016758220C007120A42D0070FC3
:2007C90080EE751C0D7582011209A97405B51708758201120A428006758200120A4290003A
:2007E90013E02430F582120A42900012E02430F582120A42758201120A9330020675825EF5
:08080900120A42C2B402019779
:202DEB00633C726D2F3938372A3635342D3332312B3D2E305354432052504E202020202087
:152E0B002020202043616C63756C61746F722076312E313000D2
:20081100AF82AEB0741F5EF5B0758232C007120E69D00753070FEFC454F0F5A075826412F0
:200831000E69D2B5758264120E69C2B522E582FFC4540FF582C007120811D0078F82120834
:2008510011020894AFA0C2B7D2B6D2B5439580AE96747F5EF596758264C007120E69A2A795
:200871009201AE95747F5EF595439680C2B5D2B5758264120E69D007C2B58FA0A201E43344
:20089100F582227E007F00C007C006120855E582D006D007700122758201C007C006120E69
:2008B1005AD006D0070EBE00010FC3EE9464EF940040D422AF82C007120894D007C2B5D21C
:2008D100B7C2B674F05FF5A0D2B5758264C007120E69D007C2B553070FEFC454F0F5A0D239
:2008F100B5758264120E69C2B50208947595007596FFAFB1740F5FF5B143B2F075821E1231
:200911000E5A758203120811758205120E5A758203120811758264120E6975820312081195
:20093100758264120E69758202120811758264120E6975820612083E75820C12083E758213
:200951001412083E75822812083E75824012083E7F00758200C0071208C5D007EF6002745C
:200971000FFE8E82C0071208C57582001208C575821C1208C57582101208C57582181208CC
:20099100C57582101208C575821C1208C5D0070FBF020040BD020AC5AF82BF0200501D7461
:2009B100F0251C4017EF030354C02480251CF582C00712083ED0078F1A851C1B22E582FF56
:2009D100700B75828012083E751A0080097582C012083E751A01751B0022AE82AD837F0074
:2009F100AC1D8E828D838FF0122D5DFB6020EC601D8B82C007C006C005C004120A42D004A9
:200A1100D005D006D0070EBE00010D1C80D422AE82AF838E828F83E493FD60148D82C00795
:200A3100C006120A42D006D0070EBE00E60F80E322AF82BF0D028003BF0A05120AC5803E9F
:200A5100E4BF090104FE7003EE6014E51A70087582011209CE80277582001209CE801F8FF4
:200A7100821208C5051B74F0251B5012E51A70087582011209CE80067582001209CE900090
:200A91000122AF82E51B6010EFB51A0C758220C007120A42D00780EC22E582540FFF24F633
:200AB100400A8F0674302EF582020A4274572FF582020A4275820112083E751A00751B0081
:010AD1002202
:200AD2007591007592007590FFAFB174FC5FF5B1AFB274FC5FF5B243B003AFC974CF5FF542
:200AF200C9AFCA74CF5FF5CA43C8307F00EF2F25E0248AFE7D00ED2EF9902E20E493FCF7DF
:200B12000DBD040040F00FBF050040E17522FF227880760043B203AFB074FC5FF5B043B0ED
:200B320003AFB274FC5FF5B27880860F30B0047E0080027E01EE2F7880F67880860F30B160
:200B5200047E0080027E02EE2F7880F67880860F30CC047E0080027E04EE2F7880F67880E2
:200B7200860F30CD047E0080027E08EE2F7880F67F00902E24E493FEC3EF9E505CEF042453
:200B920080F87600EF04FE8FF005F07401800225E0D5F0FBFD7C0074042CF5F005F07401C8
:200BB200800225E0D5F0FBF4F590ED5590FB70047A0180027A008A0BEE2480F9870A8CF07E
:200BD20005F0EB800225E0D5F0FBFB2AF77590FF0CBC040040C10F8099227522FF75240076
:200BF200E524252425E0FEFD248AF52CE5242485F52BE5242480F52A752500C00DE525258E
:200C12002CFAA80A8628A82B860FE5252525FA8AF005F07403800225E0D5F0FBFA5FF529E2
:200C3200E52575F002A4F5F005F0E5298002C313D5F0FBF529852826852927A82A860F85DB
:200C520025F005F07A017B008006EA2AFAEB33FBD5F0F78F0D7F00ED520AEF520BD00DEAA2
:200C72004B601B902E21E493FFC3E52864808FF063F08095F0501FE52804F5268018902ECB
:200C920020E493FFC364808528F063F08095F05005E52814F526E52924FC5003020DF1E519
:200CB2002975F003A4900CBB73020CC7020D07020D60020D9DC00D902E20E493FF3395E054
:200CD200FB902E23E493FA3395E0FDEA2FFFED3BFBE526FA3395E0FDC3EA9FED64808BF093
:200CF20063F08095F0D00D5003020DFD752600752701020DFD902E22E493FFC3E526648002
:200D12008FF063F08095F0400D752702902E21E493F526020DFDC00DEF3395E0FBC3E49FDD
:200D3200FFE49BFBE526FA3395E0FDC3EF9AEB64808DF063F08095F0D00D5003020DFD75DD
:200D52002700902E20E493F5260523020DFDC00D902E21E493FF3395E0FB902E23E493FA9F
:200D72003395E0FDEFC39AFFEB9DFBE526FA3395E0FDC3EF9AEB64808DF063F08095F0D084
:200D92000D40687526007527038060C00D902E22E493FFFA3395E0FBC3E49AFAE49BFBE518
:200DB20026FC3395E0FDC3EA9CEB64808DF063F08095F0D00D400C752700902E20E493F55E
:200DD200268028C3E52664808FF063F08095F0401A752702902E21E493F5260523800C7518
:200DF2002700902E20E493F52605237401B52902800A7401B52705E5252EF522ED248A25DE
:200E120025F8A626E5242485F9870FE5252525FC8CF005F07403800225E0D5F0FBF4FB52D6
:200E32000F8CF005F0E527800225E0D5F0FBFC4FF7052574FC25254003020C0D052474FBB1
:080E520025244003020BF222EB
:052E2000E21E020204A5
:1C0E5A0075F00A74E6D5E0FDD5F0F8D582F222000000000000D582F722D2B422C1
:09007500753800753900753A0078
:200E7600AD82AE83AFF0AA70AB71AC728A828B838CF0122D5DF8A3122D5DF98D828E838FF8
:200E9600F0E8122CD8A3E9122CD874022DFDE43EFE74022AF574E43BF5758C76757300E58B
:200EB600732DF8E43EF98F04C005C006C007E5732574FAE43575FBAF768A828B838FF01240
:200ED6002D5DFA888289838CF0122CD80573C3E5739409D007D006D00540C422AD82122D8A
:200EF6005DFEA3122D5DFF30E60C8E048F058C8274804DF583228E82747F5FF58322AD82E7
:200F1600AE83AFF0E572600BAB70AC7174804CF571800353717F8D828E838FF0E570122C53
:200F3600D8A3E571022CD8AD82AE83AFF074022DFDE43EFEAC70BC09005015EC2DF9E43E8B
:200F5600FA8F0389828A838BF0E4122CD80C80E622AD82AE83AFF0753A00E4F539F538F5EC
:200F76003B74022DFDE43EFEE53B2DFAE43EFB8F048A828B838CF0122D5D75F00A84F53817
:200F9600E53B2DFAE43EFB8F048A828B838CF0122D5D75F00A8485F039E53B2DFAE43EFB0D
:200FB6008F04E53A75F00AA42538F98A828B838CF0122CD885393A053B74F7253B50A92236
:200FD600AD82AE83AFF0753A00753900753800753B0874022DFDE43EFEE53B2DFAE43EFB16
:200FF6008F048A828B838CF0122D5D75F00A84F538E53B2DFAE43EFB8F048A828B838CF069
:20101600122D5D75F00A8485F039E53B2DFAE43EFB8F04E53975F00AA4253AF98A828B83E3
:201036008CF0122CD885383A153B7401253B50A92285823C85833D85F03E122D5DA3122D18
:201056005D33E433F540853C82853D83853EF0120EF28582418583427402253CF8E4353D9A
:20107600F9AC3E7B00EB28FAE439FE8C078A828E838FF0122D5D70060BBB090040E7EB753D
:20109600F002A4D39541F4B3F541E54295F0F542EB605ABB090050557402253CFDE4353D03
:2010B600FEAF3E7543008B3F74F7253F4030E5432DF544E43EF5458F46E53F2DFAE43EFB47
:2010D6008F048A828B838CF0122D5DFA8544828545838546F0122CD80543053F80CA854334
:2010F60070853C82853D83853EF0120F3D7402253CFDE4353DFEAF3E8D828E838FF0122DDE
:201116005DFDBD0A005015853C82853D83853EF0120FD6154174FFB541021542854170852E
:201136004271854072853C82853D83853EF0020F148582478583487549007C008C4A8C4BCA
:201156008C4C854782854883E0FB700990002D75F04002136CBB2D06754C02754901AB4968
:20117600EB2547F582E43548F583E0F54F742EB54F14E54C20E006434C0102136890002DD3
:2011960075F040021415C3E54F648094B15003021223C374B9854FF063F08095F05003025E
:2011B6001223BC12005020EC30E016ECC313242FF9E54A75F00AA4FFE54F24D0FE2FF78079
:2011D60006E54F24D0F54A0CE54B700F7401B54C0280057403B54C03754BFFE54C7005757F
:2011F6004C04801C7401B54C05754C0580127402B54C05754C0680087403B54C03754C070C
:20121600E54C30E003021368054B021368EB2547F582E43548F583E0FFBF305AC37483851C
:201236004CF063F08095F0E433FE601DBC12005017EC30E010ECC313FA242FF9E54A75F095
:201256000AA4F78003754A000CE54C30E01DEE6003021368E54B7006754BFE021368E54B48
:2012760020E703021368154B021368EE7003021368054B021368EF600302135FC374838544
:201296004CF063F08095F0400990002D75F04002136C90003BE0F54DA3E0F54EAA4DAF4ED1
:2012B600EC30E00FECC313FE242FF9E54A75F00AA4F70CECC313F57090002D75F040C0076C
:2012D600C002120F3DD002D007C37480854BF063F08095F05016E54BFD3395E0FE1DBDFF4E
:2012F600011EED254DFAEE354EFF8014E54B30E70FE54BFD3395E0FEED254DFAEE354EFF6A
:20131600C374FF9A74BF8FF063F08095F0400AEA9401EF64809440500990002D75F04002B0
:201336001415C3E54C64809486E433FEB40100E433F5728A708F7190002D75F040120F14A3
:2013560090002D75F04002104790002D75F0400214150B021176AD82AE83AFF0E4122CD8A2
:20137600A3122CD874022DFDE43EFE7C00EC2DF9E43EFA8F0389828A838BF0E4122CD80C09
:20139600BC090040E822AD82AE83AFF074022DFDE43EFE7C00EC2DF9E43EFA8F0389828A98
:2013B600838BF0122D5D6004758200220CBC090040E375820122AD82AE83AFF0122D5DFB5C
:2013D600A3122D5DFCBB0005BCC00280047582002274022DFDE43EFE7C00EC2DF9E43EFA77
:2013F6008F0389828A838BF0122D5DF9B9FF028004758200220CBC090040DF75820122AD0F
:2014160082AE83AFF0E4122CD8A374C0122CD874022DFDE43EFE7C00EC2DF9E43EFA8F0381
:2014360089828A838BF074FF122CD80CBC090040E722AD82AE83AFF0C007C006C0051213EA
:20145600CCE582D005D006D0076001228D828E838FF0122D5DFBA3122D5DFC902E3CE4935C
:20147600F9740193FAE96203EA62048D828E838FF0EB122CD8A3EC022CD87F0075702D8F68
:201496007175724090003D75F000C007120E7675709E75710075724090004875F000120E22
:2014B6007690003D75F00012104790004875F000121047D007E4FEFDF550F551F552F5538F
:2014D600BE09005063EF7023EE243FF582E43400F583ED244AFBE43400FCE0FA8B828C8342
:2014F600E0FBC3EA9B50047FFF8023EF7020EE243FF582E43400F583ED244AFBE43400FCFD
:20151600E0FA8B828C83E0FBC39A50027F010E0D74022550F550E43551F55174022552F5D8
:2015360052E43553F553809890003D75F000C007120EF2AD82AE83ED2550FDEE3551FE90AB
:20155600004875F000C006C005120EF2AB82AC83D005D006D007EB2552FBEC3553FCC3EBD2
:201576009DEC64808EF063F08095F0500475820122C3ED9BEE64808CF063F08095F050045F
:201596007582FF228F8222AD82AE83AFF0C007C006C005120EF2AB82AC83D005D006D007A9
:2015B600EBB55405ECB55501228D828E838FF0C007C006C005C004C003120F67D003D0045C
:2015D600D005D006D0070BBB00D60C80D375570090002D75F04012104790009E75F04012FC
:2015F600104790002D75F040120EF2AD82AE8390009E75F040C006C005120EF2AB82AC83DE
:20161600D005D006EDB50306EEB50402801890002D75F040120EF285825485835590009EC3
:2016360075F04012159D755608E556242FF9E55624A0F886058D037C00AA577F00EA2BFBB3
:20165600EF3CFC87078F027E00C3EA9BEE64808CF063F08095F0400CE5572DD39FF4FE7534
:201676005700800E74642FFFE5572DD39FF4FE755701E556242FF8A6061556E55630E7A937
:201696002275580090009E75F04012139CE58260012290002D75F04012139CE58260127556
:2016B600709E75710075724090002D75F040020E7675709E7571007572409000A975F040A3
:2016D600120E76E52E33E433FE605E789E860408E6FD20E754121490AD82BD01051215E3AD
:2016F6008035BDFF2975702D75710075724090009E75F040120E767570A975710075724017
:2017160090002D75F040120E761215E3800990002D75F04012136C7570A97571007572409A
:2017360090009E75F040020E76EE705E789E860408E6FE30E754121490AD82BD01051215B8
:20175600E38035BDFF2975702D75710075724090009E75F040120E767570A9757100757213
:201776004090002D75F040120E761215E3800990002D75F04012136C7570A975710075723A
:201796004090009E75F040020E7690002D75F04012104790009E75F04012104790002D7561
:2017B600F040120EF2AC82AE8390009E75F040C006C004120EF2AA82AB83D004D006C3EA52
:2017D6009CEB64808EF063F08095F0501B90002D75F040120EF285825485835590009E7578
:2017F600F04012159D0218A290002D75F040120EF2AC82AE8390009E75F040C006C00412E1
:201816000EF2AA82AB83D004D006C3EC9AEE64808BF063F08095F050737E0090009E75F0EC
:2018360040C006120EF2AB82AC8390002D75F040C004C003120EF2AA82AF83D003D004D04E
:2018560006EBC39AFBEC9FFCEEFA3395E0FFC3EA9BEF64808CF063F08095F0501090002D07
:2018760075F040C006120F67D0060E80AE90009E75F040120EF2858270858371E52E33E44E
:2018960033F57290002D75F040120F147F08EF242FF9EF24A0F886068704EE2C2558FE7573
:2018B600F06484E5F0F775F064EE84F5581FEF30E7DCE558604290002D75F040120EF2AEE4
:2018D60082AF83E52E33E433FD90002D75F040C007C006C005120F67D005D006D007740AA8
:2018F600252FF52F74012EF570E43FF5718D7290002D75F040120F147570A97571007572D8
:201916004090009E75F040020E767F0090002D75F040C0071213CCE582D007701190009E92
:2019360075F040C0071213CCE582D007600990002D75F0400214159000A975F040C0071249
:20195600136C90002D75F04012104790009E75F040121047D007AE2E7D00530680789E8646
:20197600030886047B00530480EB6205EC6206ED4E60027401F55A90002D75F040C0071228
:201996000EF2AC82AD8390009E75F040C005C004120EF2AA82AB83D004D005D007EA2CF580
:2019B6005BEB3DF55C755908E55924A0F97A08EA24ABF886068E057E00EA242FFCC000A8FB
:2019D600048604D00087038BF0ECA42DFDEE35F0FE8F037C00EB2DFDEC3EFE7570648C7132
:2019F6008D828E83C006C005C002C001C000122D10AB82D000D001D002D005D006A603752B
:201A160070647571008D828E83C002C001122CAFAD82AE83D001D0028D071AEA30E790E53F
:201A360059601A9000A975F040C007120F679000A975F040120F67D00778ABA6071559E530
:201A56005920E7030219BEBF0A0040249000A975F040C007120F679000A975F040120F6774
:201A7600D007055BE4B55B02055C78ABA607801FEF601C9000A975F040C007120F67D007E4
:201A9600EF75F00AA4FF78AB8606EF2E78ABF6C3E55B94FFE55C648094BF5025C3740195FA
:201AB6005B7440855CF063F08095F05014855B70855C71855A729000A975F040120F1480EE
:201AD6000990002D75F0400214157570A975710075724090002D75F040120E7690002D7595
:201AF600F04002104790002D75F04012139CE582600990002D75F04002141590002D75F0A5
:201B16004012104775702D7571007572409000BF75F040120E7690002D75F040120EF2AE3B
:201B360082AF83C3E49EFEE49FFFEE24FFF570EF34FFF571E52E33E433F5729000B475F0AB
:201B560040120F14AF2FBF1400500678B67632801ABF2100500678B6761E800FBF320050BB
:201B76000678B67614800478B6760A7F01EF24B6F876000FBF090040F47570B475710075A9
:201B9600724090002D75F040120E767F007570BF75710075724090009E75F040C007120E9B
:201BB6007612192090002D75F04012144875702675712E75728090009E75F040120E76127D
:201BD60016977570B475710075724090009E75F040120E7612192012169775702D75710031
:201BF6007572409000B475F040120E76D0070FBF060040992275702D7571007572409000D4
:201C16001475F000120E7675709E75710075724090002D75F040120E76121AFB7570147582
:201C3600710075720090009E75F040120E76021920E52E20E70D90002D75F04012139CE563
:201C560082600990002D75F04002141590002D75F04012104790002D75F040120EF2E58250
:201C76008583F02401FEE435F0FF78BFA60608A607E4F52DF52E75702675712E7572809054
:201C9600009E75F040120E76789E760108760090002D75F04012144812169775702D7571C3
:201CB600007572409000B475F040120E767F00EF600D9000B475F040C007120FD6D007759A
:201CD60070B475710075724090002D75F040C007120E76D0077E00E52E30E703021D867562
:201CF600702D7571007572409000B475F040C007C006120E7675702D757100757240900069
:201D16009E75F040120E76D006D0077D00C3ED9F501890009E75F040C007C006C005120FAD
:201D360067D005D006D0070D80E3C007C006121697D006D00774F6252F502B90002D75F0E0
:201D560040C007C006120EF2AC82AD83D006D007C3E49C74808DF063F08095F05008E52F0B
:201D760024F6F52F8006752DFF752EFF0E021CEDEF24C1F9EE14F70FBF09005003021CC55A
:201D96007570B475710075724090002D75F040120E767F08EF75F00BA4243EFD742E35F0DF
:201DB600FEEF24C1F97C008703C3EC9B50318D708E7175728090009E75F040C007C006C0EE
:201DD60005C004C001120E76789E7600087600121697D001D004D005D006D0070C80C890F9
:201DF600002D75F040C007120F67D0071FBF090040A290002D75F04012144875702D757144
:201E1600007572409000B475F040120E7690002D75F04012136C78BF860608E6FF30E71339
:201E3600755D01C3E49EFEE49FFF78BFA60608A6078003755D0078BF8606088607C3EE946A
:201E560010EF648094A740607570107571278E828F83122DAFAB828B2F78BF868208868365
:201E7600757010757127122D79AB82AC8378BFA60308A6047570647571008B828C83C00495
:201E9600C003122DAFAA82D003D0048A307570647571008B828C83122D79AC82AD838C31D0
:201EB600752D05752E008042C3EE9464EF64809480402F7570647571008E828F83122DAFC2
:201ED600AC828C2F78BF8682088683757064757100122D79AC82AD838C30752D03752E006A
:201EF60080088E2F752D01752E00E55D600990002D75F04012144875703175712E75728035
:201F160090009E75F040120E761219207570B475710075724090009E75F040120E760216D0
:201F360097121C4775703175712E75728090009E75F040120E7675702D75710075724090D6
:201F5600001475F000120E7675709E75710075724090002D75F040120E76121AFB757014B4
:201F760075710075720090009E75F040120E76021920755F0090002D75F0401213CCE5824C
:201F9600600990002D75F040021415E52E30E70C90002D75F040121448755F0175702D75D3
:201FB60071007572409000B475F040120E7690009E75F04012136C78A0761D78A1762F78AF
:201FD6009E760208760090009E75F040121448121697E52E20E70990002D75F040021415A7
:201FF6007570B475710075724090002D75F040120E7675703175712E75728090009E75F009
:2020160040120E7675702D7571007572409000B475F040120E7675702675712E7572809020
:20203600002D75F040120E76752D01752E0012192075702D75710075724090009E75F0409F
:20205600120E7690009E75F0401214487570B475710075724090002D75F040120E767E0077
:20207600E52E20E71C75702D7571007572409000B475F040C006120E76121697D0060E808D
:20209600DF7D00EE24FFF570ED34FFF57190000A122CF3E5828583F078BFF608A6F07570F8
:2020B600B475710075724090002D75F040120E7675703175712E75728090009E75F04012DB
:2020D6000E7690009E75F0401214487EFF7D00E52E20E72075702D7571007572409000B48E
:2020F60075F040C006C005120E76121697D005D0060D80DBBEFF1F78BF86030886048D0275
:202116007F001ABAFF011FEA2BFBEF3CFC78BFA60308A6048007EE24C1F9ED14F77570B48A
:2021360075710075724090002D75F040C006120E76D0060EBE0900502DEE75F00BA4243E32
:20215600FD742E35F0FF8D708F7175728090009E75F040C006120E7690009E75F04012141A
:2021760048D0060220E375702675712E75728090009E75F040120E76121697757026757187
:202196002E75728090009E75F040120E76789E76010876007FFFEF24C1F9E4BFFF0104FE30
:2021B600755E00EE600978BF8603088604800687028A037C00AA5E7D00C3EA9BED64808C4B
:2021D600F063F08095F05013C007C006C001121920D001D006D007055E80C80FBF09005055
:2021F6002CEF700D78A07614789E760008760080A5BF010678A0760B809C90009E75F04012
:20221600C007120F67D00778A0760A8089E55F6003021AFB2275703175712E7572809000E0
:202236009E75F040120E76121920021F8890009E75F04012139CE582601275702675712E2F
:2022560075728090002D75F040020E7690002D75F04012139CE582600990002D75F04002C2
:20227600136C75709E75710075724090001475F000120E76121C477570147571007572005F
:2022960090009E75F040120E76121920021F8890001F7445F09000207472F0900021F090BC
:2022B6000022746FF09000237472F0900024E4F022AD82AE83AFF07C008C617A008D828E61
:2022D600838FF0C007C006C005C004C0021213CCE582D002D004D005D006D00760071222F3
:2022F600A5758200228D708E718F7290005375F000C004C002120E7690005375F00012103F
:2023160047D002D004900055E0700F90001F7430F0900020E4F075820022900053E0FEA332
:20233600E0FF30E70890001F742DF07C0190005375F000C004C002120EF2AE82AF83D002B8
:20235600D004902E25E493FDF8790018B8FF0119C3E89EE964808FF063F08095F0400AEEBD
:2023760094FDEF6480947F50027A01EA7057EF30E753EC241FF582E43400F5837430F00C23
:202396008C010CE9241FF582E43400F583742EF0C3E49EF8E49FF918B8FF01198C62C3E492
:2023B60098748089F063F08095F05017E562241FF582E43400F5837430F0056218B8FF01E7
:2023D6001980DBAC62EC241FF8E43400F9900055E075F00A842430FB88828983F00CEA60CA
:2023F600128C030CEB241FF582E43400F583742EF08019EE4F70108C030CEB241FF582E4D9
:202416003400F583742EF01EBEFF011FEC241FF9E43400FB900055E075F00A84A8F074303E
:2024360028F889828B83F0900055E0FB75F00A84E5F0700AEA7004EF30E7037561010CEA27
:202456007019EE4F70108C030CEB241FF582E43400F583742EF01EBEFF011FEDC313FD758E
:202476006001C3E5609D400302255CEC241FF8E43400F9E5602455F582E43400F583E07528
:20249600F00A842430FB88828983F00CEA7019EE4F70108C030CEB241FF582E43400F58347
:2024B600742EF01EBEFF011FEC241FF9E43400FBE5602455F582E43400F583E075F00A84A6
:2024D600A8F0743028F889828B83F00CEA7019EE4F70108C030CEB241FF582E43400F58375
:2024F600742EF01EBEFF011FE5602455F9E43400FB89828B83E07025EA7004EF30E71EEA75
:20251600700BC3EE94FEEF6480947F500605610561802EBEFE2BBFFF2805618024E56024F1
:2025360055F582E43400F583E0FB75F00A84E5F0700CEA7004EF30E7057561018003756171
:20255600000560022478EA700EC3E49E74808FF063F08095F04005ECC39561FCEC241FF5E0
:2025760082E43400F583E4F090005375F000C002120EF2AE82AF83D002EA6023C374809E4D
:2025960074808FF063F08095F0400AEE9480EF6480947F50071222A5758200228E82227538
:0325B6008200227E
:202E25001000000A0000000000000000000017023A325C63282D440080FF7F451F2F1205EE
:202E45003B5E3509FE7F5F1F014F502B185600FD7F633221083510505254FC7F635F00218F
:202E65001E53351F43FB7F636332002121082121FA7F63635F000021211D5FF97F6363634A
:1C2E8500320000210523F87F6363635F0000024C28F77F6363636332000F62415B
:08007E00756300756400C20205
:2025B9007403556475F00BA42474FE740035F0FF7D0074032564540375F00BA42474FB74A1
:2025D9000035F0FC8B708C718D728E828F838DF0120E76056422AE82AF83E5637002156475
:2025F9009000A0E0FCA3E0FD90003BECF0EDA3F08E828F831211477403556475F00BA4241B
:2026190074FE740035F0FF7D0075702D8D717572408E828F838DF0020E767403556475F029
:202639000BA42474FE740035F0FF7D008E828F838DF002136C7403556475F00BA42474F536
:2026590082740035F0F58322E56404540375F00BA42474F582740035F0F58322AE82AF8350
:20267900E56404540375F00BA42474FC740035F0FD7B008C828D838BF0C007C0061213CCCD
:20269900E582D006D00770277403556475F00BA42474FC740035F0FD7B008C828D838BF0F4
:2026B900C007C0061213CCE582D006D007601FE56404540375F00BA42474FC740035F0FD0E
:2026D9007B008C828D838BF01214150227837403556475F00BA42474FC740035F0FD8C707C
:2026F9008D7175720090006975F000C007C006120E76E56404540375F00BA42474FC74009B
:2027190035F0FD8C708D7175720090002D75F040120E767403556475F00BA42474FC740059
:2027390035F0FD8C708D7175720090009E75F040120E76D006D007C007C0068E828F8312A6
:202759000011D006D007E56404540375F00BA42474FE740035F0FF7D0075702D8D71757248
:20277900408E828F838DF0120E760225B9AE82AF837403556475F00BA42474FC740035F018
:20279900FD7B008C828D838BF0C007C0061213CCE582D006D0076001227403556475F00B5A
:2027B900A42474FC740035F0FD8C708D7175720090006975F000C007C006120E7674035504
:2027D9006475F00BA42474FC740035F0FD8C708D7175720090002D75F040120E76D006D0BF
:2027F90007C007C0068E828F83120011D006D0077403556475F00BA42474FE740035F0FFC8
:202819007D0075702D8D717572408E828F838DF0020E76B20222AF82C007120E73D007BFCF
:202839002A030228D0BF2B028055BF2D030228D6BF2E0302298CBF2F03022900BF340302ED
:202859002B86BF3503022B8FBF3603022B9CBF3703022BC3BF3803022BB6BF3903022BA9A3
:20287900BF3C030229CEBF3D03022906BF63030229B3BF6D03022B83BF7203022AE22230A2
:20289900022F7401B56302800215647403556475F00BA42474FE740035F0FF7D0075706927
:2028B9007571008D728E828F838DF0120E76C20222901697022675901920022675740355F3
:2028D9006475F00BA42474FE740035F0FF7D008E828F838DF0121448901697122675900035
:2028F9006975F000021448901C0B02267530022F7401B56302800215647403556475F00BB4
:20291900A42474FE740035F0FF7D0075705E7571008D728E828F838DF0120E76C202227498
:2029390003556475F00BA42474FE740035F0FF7D008E828F838DF01213CCE5826001221574
:20295900647403556475F00BA42474FE740035F0FF7D00E56404540375F00BA42474FB744C
:202979000035F0FC8B708C718D728E828F838DF0020E76200201227403556475F00BA42454
:2029990074FE740035F0FF8E708F7175720090005E75F000120E76C202227403556475F0CB
:2029B9000BA42474FE740035F0FF7D008E828F838DF002136C100203022AA77403556475F7
:2029D900F00BA42474FE740035F0FF7D008E828F838DF012139CE5826001227403556475A5
:2029F900F00BA42474FE740035F0FF7D008E828F838DF01213CCE582600122740355647555
:202A1900F00BA42474FE740035F0FF8E708F7175720090006975F000120E76740355647552
:202A3900F00BA42474FE740035F0FF8E708F7175720090002D75F040120E76E52E30E71B8E
:202A59007403556475F00BA42474FE740035F0FF7D008E828F838DF002141590009E75F011
:202A79004012136C78A076051222437403556475F00BA42474FE740035F0FF7D0075702D61
:202A99008D717572408E828F838DF0020E767403556475F00BA42474FE740035F0FF7D00E4
:202AB9008E828F838DF01213CCE5826001227403556475F00BA42474FE740035F0FF7D0094
:202AD9008E828F838DF00214481002028006901AFB0227867403556475F00BA42474FE74A4
:202AF9000035F0FF7D008E828F838DF01213CCE5826001227403556475F00BA42474FE7454
:202B19000035F0FF8E708F7175720090006575F040120E767403556475F00BA42474FE7415
:202B39000035F0FF7D00E56404540375F00BA42474FB740035F0FC8B708C718D728E828F65
:202B5900838DF0120E76E56404540375F00BA42474FE740035F0FF7D007570658D71757234
:202B7900408E828F838DF0020E7602282C200201220564C2022220020122901F88122786B2
:202B9900C202222002012290222B122786C2022220020122901F37122786C202222002017C
:202BB90022901C47122786C20222E56404540375F00BA42474FE740035F0FF7D008E828F40
:202BD900838DF01213CCE582701F7403556475F00BA42474FE740035F0FF7D008E828F83E4
:202BF9008DF01213CCE582601FE56404540375F00BA42474FE740035F0FF7D008E828F83E3
:202C19008DF0121415022CA97403556475F00BA42474FE740035F0FF8E708F717572009025
:202C3900006975F000120E76E56404540375F00BA42474FE740035F0FF8E708F717572004C
:202C590090002D75F040120E767403556475F00BA42474FE740035F0FF8E708F717572000C
:202C790090009E75F040120E76122243E56404540375F00BA42474FE740035F0FF7D007583
:162C9900702D8D717572408E828F838DF0120E761225B9C2022258
:202CAF007A10E4FBFCE58225E0F582E58333F583EB33FBEC33FCEB9570F5F0EC9571400669
:092CCF00FCABF0438201DADD22C6
:06004200E478FFF6D8FD92
:200020007900E94400601B7A00902EA178A275A000E493F2A308B8000205A0D9F4DAF27516
:02004000A0FF1F
:1B2CD80020F71130F6138883A88220F509F6A8837583002280FEF280F5F022FB
:1D2CF300E5828570F0A4C582C0F08571F0A4D0F025F0C5838570F0A42583F583226B
:202D1000E570457160467A01E57025E0F570E571334012F571E5829570E583957140030A50
:202D300080E6C3E57113F571E57013F570C3E5829570F5F0E58395714005F58385F082C3C5
:0D2D5000E57113F571E57013F570DAE122FD
:200048007800E84400600A790175A000E4F309D8FC78A1E84400600C7901900001E4F0A314
:04006800D8FCD9FAED
:0F001100E4737581C9122DE7E582600302000ECA
:1C2D5D0020F71430F6148883A88220F507E6A88375830022E280F7E49322E02285
:202D7900C2D5E58330E70DD2D5E4C39582F582E49583F583E57130E70BE4C39570F570E45A
:162D99009571F571122D1030D50BE4C39582F582E49583F583228E
:202DAF00C2D5E58330E70DD2D5E4C39582F582E49583F583E57130E70DB2D5E4C39570F5EF
:182DCF0070E49571F571122CAF30D50BE4C39582F582E49583F5832264
:042DE70075820022CF
:00000001FF

View File

@ -253,16 +253,7 @@ void process_cmd(char cmd){
} break; } break;
////////// //////////
case '7':{ //y^x case '7':{ //y^x
if (decn_is_nan(&stack(STACK_Y)) || decn_is_nan(&stack(STACK_X))){ do_binary_op(pow_decn);
set_dec80_NaN(&stack(STACK_Y));
} else {
copy_decn(&LastX, &stack(STACK_X)); //save LastX
copy_decn(&AccDecn, &stack(STACK_Y));
copy_decn(&BDecn, &stack(STACK_X));
pow_decn();
copy_decn(&stack(STACK_Y), &AccDecn);
}
pop();
} break; } break;
////////// //////////
} //switch(cmd) } //switch(cmd)

View File

@ -35,6 +35,7 @@
// #define DEBUG_LOG_ALL //even more verbose // #define DEBUG_LOG_ALL //even more verbose
// #define DEBUG_EXP // #define DEBUG_EXP
// #define DEBUG_EXP_ALL //even more verbose // #define DEBUG_EXP_ALL //even more verbose
// #define DEBUG_SQRT
#ifndef DESKTOP #ifndef DESKTOP
//#undef EXTRA_CHECKS //#undef EXTRA_CHECKS
@ -47,6 +48,7 @@
#undef DEBUG_LOG_ALL #undef DEBUG_LOG_ALL
#undef DEBUG_EXP #undef DEBUG_EXP
#undef DEBUG_EXP_ALL #undef DEBUG_EXP_ALL
#undef DEBUG_SQRT
#endif #endif
#ifdef DESKTOP #ifdef DESKTOP
@ -68,8 +70,8 @@ static const uint8_t num_digits_display = 16;
dec80 AccDecn; dec80 AccDecn;
__idata dec80 BDecn; __idata dec80 BDecn;
__idata dec80 TmpDecn; //used by add_decn() and mult_decn() and sqrt_decn() __idata dec80 TmpDecn; //used by add_decn() and mult_decn() and sqrt_decn()
__idata dec80 Tmp2Decn; //used by recip_decn() and ln_decn() and sincos_decn() and sqrt_decn() __idata dec80 Tmp2Decn; //used by recip_decn(), ln_decn(), exp_decn(), sqrt_decn(), and sincos_decn()
__xdata dec80 Tmp3Decn; //used by recip_decn() and ln_decn() and sincos_decn() and sqrt_decn() __idata dec80 Tmp3Decn; //used by ln_decn(), exp_decn(), sqrt_decn(), and sincos_decn()
__xdata dec80 Tmp4Decn; //used by sincos_decn() __xdata dec80 Tmp4Decn; //used by sincos_decn()
__xdata dec80 TmpStackDecn[4]; __xdata dec80 TmpStackDecn[4];
@ -78,11 +80,6 @@ __idata uint8_t TmpStackPtr;
__xdata char Buf[DECN_BUF_SIZE]; __xdata char Buf[DECN_BUF_SIZE];
//1 constant
const dec80 DECN_1 = {
0, {10, 0}
};
//ln(10) constant //ln(10) constant
const dec80 DECN_LN_10 = { const dec80 DECN_LN_10 = {
0, {23, 2, 58, 50, 92, 99, 40, 45, 68} 0, {23, 2, 58, 50, 92, 99, 40, 45, 68}
@ -425,6 +422,11 @@ void set_dec80_zero(dec80* dest){
} }
} }
void set_decn_one(dec80* dest){
set_dec80_zero(dest);
dest->lsu[0] = 10;
}
uint8_t decn_is_zero(const dec80* x){ uint8_t decn_is_zero(const dec80* x){
uint8_t i; uint8_t i;
for (i = 0; i < DEC80_NUM_LSU; i++){ for (i = 0; i < DEC80_NUM_LSU; i++){
@ -872,14 +874,12 @@ void recip_decn(void){
} else { } else {
CURR_RECIP.lsu[0] = 10; //0.1 with implicit point and exponent CURR_RECIP.lsu[0] = 10; //0.1 with implicit point and exponent
} }
for (i = 1; i < DEC80_NUM_LSU; i++){ zero_remaining_dec80(&CURR_RECIP, 1);
CURR_RECIP.lsu[i] = 0;
}
copy_decn(&AccDecn, &CURR_RECIP); copy_decn(&AccDecn, &CURR_RECIP);
//do newton raphson iterations //do newton-raphson iterations
for (i = 0; i < 6; i++){ //just fix number of iterations for now for (i = 0; i < 6; i++){ //just fix number of iterations for now
#ifdef DEBUG_DIV #ifdef DEBUG_DIV
decn_to_str_complete(&curr_recip); decn_to_str_complete(&CURR_RECIP);
printf("%2d: %s\n", i, Buf); printf("%2d: %s\n", i, Buf);
#endif #endif
//Accum *= x_copy //Accum *= x_copy
@ -892,7 +892,7 @@ void recip_decn(void){
//Accum *= -1 //Accum *= -1
negate_decn(&AccDecn); negate_decn(&AccDecn);
//Accum += 1 //Accum += 1
copy_decn(&BDecn, &DECN_1); set_decn_one(&BDecn);
add_decn(); add_decn();
#ifdef DEBUG_DIV #ifdef DEBUG_DIV
decn_to_str_complete(&AccDecn); decn_to_str_complete(&AccDecn);
@ -962,7 +962,7 @@ void ln_decn(void){
printf("ln() accum scaled between 1,10: %s\n", Buf); printf("ln() accum scaled between 1,10: %s\n", Buf);
#endif #endif
//get initial estimate (accum = 10 - A) //get initial estimate (accum = 10 - A)
copy_decn(&BDecn, &DECN_1); set_decn_one(&BDecn);
BDecn.exponent = 1; //BDecn = 10 BDecn.exponent = 1; //BDecn = 10
negate_decn(&AccDecn); negate_decn(&AccDecn);
add_decn(); add_decn();
@ -1139,7 +1139,7 @@ void exp_decn(void){
//initial b = -10*ln(10) //initial b = -10*ln(10)
copy_decn(&BDecn, &DECN_LN_10); //b=ln(10) copy_decn(&BDecn, &DECN_LN_10); //b=ln(10)
copy_decn(&SAVED, &AccDecn); //save = accum copy_decn(&SAVED, &AccDecn); //save = accum
copy_decn(&AccDecn, &DECN_1); set_decn_one(&AccDecn);
AccDecn.exponent = 1; //accum = 10 AccDecn.exponent = 1; //accum = 10
mult_decn(); //accum = 10*ln(10) mult_decn(); //accum = 10*ln(10)
copy_decn(&BDecn, &AccDecn); //b = 10*ln(10) copy_decn(&BDecn, &AccDecn); //b = 10*ln(10)
@ -1208,10 +1208,10 @@ void exp_decn(void){
//build final value //build final value
// (currently accum = save = remainder) // (currently accum = save = remainder)
// calculate 1+remainder // calculate 1+remainder
copy_decn(&BDecn, &DECN_1); set_decn_one(&BDecn);
add_decn(); add_decn();
//get initial multiplier (10) for ln(10) //get initial multiplier (10) for ln(10)
copy_decn(&BDecn, &DECN_1); set_decn_one(&BDecn);
BDecn.exponent = 1; //BDecn = 10 BDecn.exponent = 1; //BDecn = 10
//do multiplies //do multiplies
j = UINT8_MAX; //becomes 0 after incrementing to start (1 + 10^-j) series j = UINT8_MAX; //becomes 0 after incrementing to start (1 + 10^-j) series
@ -1273,7 +1273,7 @@ void exp10_decn(void){
void pow_decn(void) { void pow_decn(void) {
if (decn_is_zero(&BDecn)) { if (decn_is_zero(&BDecn)) {
copy_decn(&AccDecn, &DECN_1); set_decn_one(&AccDecn);
return; return;
} }
if (decn_is_zero(&AccDecn)) { if (decn_is_zero(&AccDecn)) {
@ -1288,6 +1288,144 @@ void pow_decn(void) {
exp_decn(); exp_decn();
} }
#ifdef USE_POW_SQRT_IMPL
void sqrt_decn(void) {
if (decn_is_zero(&AccDecn)) {
return;
}
if (decn_is_nan(&AccDecn)) {
return;
}
if (AccDecn.exponent < 0){ //negative
set_dec80_NaN(&AccDecn);
return;
}
st_push_decn(&BDecn); // sqrt should behave like an unary operation
//b = 0.5
set_dec80_zero(&BDecn);
BDecn.lsu[0] = 5;
pow_decn();
st_pop_decn(&BDecn);
}
#else
void sqrt_decn(void){
#define CURR_EST Tmp2Decn //holds current 1/sqrt(x) estimate
#define X_2 Tmp3Decn //holds copy of original x / 2
uint8_t i;
exp_t initial_exp;
if (decn_is_nan(&AccDecn)) {
return;
}
if (AccDecn.exponent < 0){ //negative
set_dec80_NaN(&AccDecn);
return;
}
//normalize
remove_leading_zeros(&AccDecn);
#ifdef DEBUG_SQRT
decn_to_str_complete(&AccDecn);
printf("sqrt in: %s\n", Buf);
#endif
//store copy of x
st_push_decn(&AccDecn);
//calculate x_orig / 2
set_dec80_zero(&BDecn);
BDecn.lsu[0] = 5;
mult_decn();
copy_decn(&X_2, &AccDecn);
//restore x
st_load_decn(&AccDecn);
//get initial estimate for 1/sqrt(x) == 10^(-0.5 * log(x)):
// approximate significand == 10^(-0.5 * log(x_signif))
// with linear approximation: -0.18 * x_signif + 2.5
// new exponent part is (10^(-0.5 * log(10^x_exp)))
// == 10^(-0.5 * x^exp)
initial_exp = get_exponent(&AccDecn);
set_exponent(&AccDecn, 0, 0); //clear exponent (Acc is not negative)
#ifdef DEBUG_SQRT
printf("sqrt exponent %d ", initial_exp);
#endif
if (initial_exp & 0x1){ //odd
#ifdef DEBUG_SQRT
printf("(odd) ");
#endif
//increment x_exp and
initial_exp++;
//approximate estimated significand as (-0.056*x_signif + 0.79) * 10^0.5
// == -0.18 * x_signif + 2.5
//b = -0.18
BDecn.lsu[0] = 18;
BDecn.exponent = -1; //negative, and exponent = -1
//a = -0.18 * x_signif
mult_decn();
//b = 2.5
BDecn.lsu[0] = 25;
BDecn.exponent = 0;
//a = -0.18 * x_signif + 2.5
add_decn();
} else { //even
//keep x_exp as is and approximate estimated significand as
// -0.056*x_signif + 0.79
//b = -0.056
BDecn.lsu[0] = 56;
set_exponent(&BDecn, -2, 1);
//a = -0.056 * x_signif
mult_decn();
//b = 0.79
BDecn.lsu[0] = 7;
BDecn.lsu[1] = 90;
BDecn.exponent = 0;
//a = -0.056*x_signif + 0.79
add_decn();
}
//est_exp = -x_exp / 2;
initial_exp = -initial_exp / 2;
//est_exp-- if AccDecn exponent is negative
// (AccDecn exponent is either 0 or -1, and AccDecn is positive)
if (AccDecn.exponent != 0){
initial_exp--;
}
set_exponent(&AccDecn, initial_exp, 0); //(initial estimate is never negative)
copy_decn(&CURR_EST, &AccDecn);
#ifdef DEBUG_SQRT
printf(" -> %d\n", initial_exp);
#endif
//do newton-raphson iterations
for (i = 0; i < 6; i++){ //just fix number of iterations for now
#ifdef DEBUG_SQRT
decn_to_str_complete(&CURR_EST);
printf("sqrt %2d: %s\n", i, Buf);
#endif
//accum = est * est;
copy_decn(&BDecn, &AccDecn);
mult_decn();
//accum *= x_orig_2; //accum = x/2 * est * est
copy_decn(&BDecn, &X_2);
mult_decn();
//accum = - x/2 * est * est
negate_decn(&AccDecn);
//b = 3/2
set_dec80_zero(&BDecn);
BDecn.lsu[0] = 15;
//accum = 3/2 - x/2 * est * est
add_decn();
//accum *= est; //accum = 0.5 * est * (3 - x * est * est)
copy_decn(&BDecn, &CURR_EST);
mult_decn();
//est = accum;
copy_decn(&CURR_EST, &AccDecn);
}
//calc sqrt from recip_sqrt
st_pop_decn(&BDecn);
mult_decn();
#undef CURR_EST
#undef X_COPY
}
#endif //USE_POW_SQRT_IMPL
// see W.E. Egbert, "Personal Calculator Algorithms II: Trigonometric functions" // see W.E. Egbert, "Personal Calculator Algorithms II: Trigonometric functions"
void project_decn_into_0_2pi(void) { void project_decn_into_0_2pi(void) {
const uint8_t is_negative = (AccDecn.exponent < 0); const uint8_t is_negative = (AccDecn.exponent < 0);
@ -1333,11 +1471,11 @@ void sincos_decn(const uint8_t sincos_arctan) {
set_dec80_zero(&THETA); set_dec80_zero(&THETA);
if (is_negative) negate_decn(&AccDecn); if (is_negative) negate_decn(&AccDecn);
copy_decn(&COS, &AccDecn); copy_decn(&COS, &AccDecn);
copy_decn(&SIN, &DECN_1); set_decn_one(&SIN);
} else { } else {
project_decn_into_0_2pi(); project_decn_into_0_2pi();
copy_decn(&THETA, &AccDecn); copy_decn(&THETA, &AccDecn);
copy_decn(&COS, &DECN_1); set_decn_one(&COS);
set_dec80_zero(&SIN); set_dec80_zero(&SIN);
// 0.0 00 5 // 0.0 00 5
SIN.lsu[2] = 50; SIN.lsu[2] = 50;
@ -1409,7 +1547,7 @@ void arcsin_decn(void) {
copy_decn(&BDecn, &AccDecn); copy_decn(&BDecn, &AccDecn);
mult_decn(); mult_decn();
negate_decn(&AccDecn); negate_decn(&AccDecn);
copy_decn(&BDecn, &DECN_1); set_decn_one(&BDecn);
add_decn(); add_decn();
sqrt_decn(); sqrt_decn();
recip_decn(); recip_decn();
@ -1446,25 +1584,6 @@ void pi_decn(void) {
mult_decn(); mult_decn();
} }
void sqrt_decn(void) {
if (decn_is_zero(&AccDecn)) {
return;
}
if (decn_is_nan(&AccDecn)) {
return;
}
if (AccDecn.exponent < 0){ //negative
set_dec80_NaN(&AccDecn);
return;
}
st_push_decn(&BDecn); // sqrt should behave like an unary operation
//b = 0.5
set_dec80_zero(&BDecn);
BDecn.lsu[0] = 5;
pow_decn();
st_pop_decn(&BDecn);
}
static void set_str_error(void){ static void set_str_error(void){
Buf[0] = 'E'; Buf[0] = 'E';
Buf[1] = 'r'; Buf[1] = 'r';

View File

@ -69,6 +69,7 @@ extern __idata uint8_t TmpStackPtr;
void build_dec80(__xdata const char* signif_str, __xdata exp_t exponent); void build_dec80(__xdata const char* signif_str, __xdata exp_t exponent);
void set_dec80_zero(dec80* dest); void set_dec80_zero(dec80* dest);
void set_decn_one(dec80* dest);
void set_dec80_NaN(dec80* dest); void set_dec80_NaN(dec80* dest);
uint8_t decn_is_zero(const dec80* x); uint8_t decn_is_zero(const dec80* x);
uint8_t decn_is_nan(const dec80* x); uint8_t decn_is_nan(const dec80* x);

View File

@ -341,6 +341,51 @@ TEST_CASE("division"){
); );
} }
static void sqrt_test(const char* x_str, int x_exp)
{
CAPTURE(x_str); CAPTURE(x_exp);
build_dec80(x_str, x_exp);
// decn_to_str_complete(&AccDecn);
// printf(" acc: %s\n", Buf);
sqrt_decn();
decn_to_str_complete(&AccDecn);
CAPTURE(Buf); // sqrt(x)
//calculate actual result
bmp::mpfr_float::default_precision(50);
std::string x_full_str(x_str);
x_full_str += "e" + std::to_string(x_exp);
CAPTURE(x_full_str);
bmp::mpfr_float x_actual(x_full_str);
CAPTURE(x_actual);
if (decn_is_nan(&AccDecn)){
//check that NaN is from result of sqrt(-)
CHECK(x_actual <= 0);
} else if (decn_is_zero(&AccDecn)){
//check actual is also 0
CHECK(x_actual == 0);
} else {
x_actual = sqrt(x_actual);
bmp::mpfr_float calculated(Buf);
bmp::mpfr_float rel_diff = abs((x_actual - calculated) / x_actual);
CHECK(rel_diff < 3e-16); //TODO
}
}
TEST_CASE("sqrt"){
sqrt_test("0", 0);
sqrt_test("2", 0);
sqrt_test("-1", 0);
sqrt_test("0.155", 0);
sqrt_test("10", 0);
sqrt_test("1.1", 10);
sqrt_test("2.02", -10);
sqrt_test("2.02", 0);
sqrt_test("1.5", 0);
sqrt_test("9", 99);
sqrt_test("123", 12345);
}
static void log_test( static void log_test(
//input //input
const char* x_str, int x_exp, const char* x_str, int x_exp,

View File

@ -23,7 +23,7 @@
#include <boost/multiprecision/mpfr.hpp> #include <boost/multiprecision/mpfr.hpp>
using namespace boost::multiprecision; using namespace boost::multiprecision;
// #define DEBUG #define DEBUG
using std::cout; using std::cout;
using std::endl; using std::endl;
@ -51,7 +51,7 @@ int main(void){
//loop through values to test //loop through values to test
#ifdef DEBUG #ifdef DEBUG
mpfr_float x(0.1, CALC_PRECISION); mpfr_float x(2.0, CALC_PRECISION);
{ {
#else #else
for (mpfr_float x(1e-99, CALC_PRECISION); x < 1e99; x *= 1.03){ for (mpfr_float x(1e-99, CALC_PRECISION); x < 1e99; x *= 1.03){
@ -87,7 +87,7 @@ int main(void){
x_exp++; x_exp++;
est_signif = -0.18 * x_signif + 2.5; est_signif = -0.18 * x_signif + 2.5;
} else { //even } else { //even
//keep x_exp as is and approximate estimate significand as //keep x_exp as is and approximate estimated significand as
// -0.056*x_signif + 0.79 // -0.056*x_signif + 0.79
est_signif = -0.056 * x_signif + 0.79; est_signif = -0.056 * x_signif + 0.79;
} }

View File

@ -3,6 +3,8 @@
""" """
Created on Wed Dec 11 00:56:01 2019 Created on Wed Dec 11 00:56:01 2019
Calculate constants used for "0x5F3759DF" reciprocal sqrt
@author: jeffrey @author: jeffrey
""" """

View File

@ -140,7 +140,7 @@ static void latch_on(void)
__xdata char EntryBuf[MAX_CHARS_PER_LINE + 1]; __xdata char EntryBuf[MAX_CHARS_PER_LINE + 1];
__xdata uint8_t ExpBuf[2]; __xdata uint8_t ExpBuf[2];
__code const char VER_STR[32+1] = "STC RPN Calculator v1.11"; __code const char VER_STR[32+1] = "STC RPN Calculator v1.12";
enum { enum {