version bump 1.0.5: adjusting tolerance
This commit is contained in:
parent
63e6cf4bb3
commit
93ff7f307a
@ -1,13 +1,14 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "5.0"
|
||||
- "6"
|
||||
- "5"
|
||||
- "4.2"
|
||||
- "0.12"
|
||||
- "0.10"
|
||||
- "0.8"
|
||||
before_install:
|
||||
- "npm install -g npm@next"
|
||||
- "npm install -g mocha"
|
||||
- "npm install -g mocha voc"
|
||||
- "npm install blanket"
|
||||
- "npm install coveralls mocha-lcov-reporter"
|
||||
after_success:
|
||||
|
63
Makefile
63
Makefile
@ -2,56 +2,57 @@ LIB=frac
|
||||
REQS=
|
||||
ADDONS=
|
||||
AUXTARGETS=
|
||||
HTMLLINT=index.html
|
||||
|
||||
ULIB=$(shell echo $(LIB) | tr a-z A-Z)
|
||||
DEPS=$(LIB).md
|
||||
TARGET=$(LIB).js
|
||||
FLOWTARGET=$(LIB).flow.js
|
||||
|
||||
## Main Targets
|
||||
|
||||
.PHONY: all
|
||||
all: $(TARGET) $(AUXTARGETS)
|
||||
all: $(TARGET) $(AUXTARGETS) ## Build library and auxiliary scripts
|
||||
|
||||
$(TARGET) $(AUXTARGETS): %.js : %.flow.js
|
||||
node -e 'process.stdout.write(require("fs").readFileSync("$<","utf8").replace(/^\s*\/\*:[^*]*\*\/\s*(\n)?/gm,"").replace(/\/\*:[^*]*\*\//gm,""))' > $@
|
||||
node -e 'process.stdout.write(require("fs").readFileSync("$<","utf8").replace(/^[ \t]*\/\*[:#][^*]*\*\/\s*(\n)?/gm,"").replace(/\/\*[:#][^*]*\*\//gm,""))' > $@
|
||||
|
||||
$(LIB).flow.js: $(DEPS)
|
||||
$(FLOWTARGET): $(DEPS)
|
||||
voc $^
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -f $(TARGET)
|
||||
clean: ## Remove targets and build artifacts
|
||||
rm -f $(TARGET) $(FLOWTARGET)
|
||||
|
||||
## JavaScript
|
||||
|
||||
.PHONY: test mocha
|
||||
test mocha: test.js
|
||||
test mocha: test.js $(TARGET) ## Run JS test suite
|
||||
mocha -R spec -t 20000
|
||||
|
||||
.PHONY: lint
|
||||
lint: $(TARGET) $(AUXTARGETS)
|
||||
jshint --show-non-errors $(TARGET) $(AUXTARGETS)
|
||||
jshint --show-non-errors package.json
|
||||
jscs $(TARGET) $(AUXTARGETS)
|
||||
lint: $(TARGET) $(AUXTARGETS) ## Run jshint and jscs checks
|
||||
@jshint --show-non-errors $(TARGET) $(AUXTARGETS)
|
||||
@jshint --show-non-errors package.json
|
||||
@jshint --show-non-errors --extract=always $(HTMLLINT)
|
||||
@jscs $(TARGET) $(AUXTARGETS)
|
||||
|
||||
.PHONY: flow
|
||||
flow: lint
|
||||
flow check --all --show-all-errors
|
||||
flow: lint ## Run flow checker
|
||||
@flow check --all --show-all-errors
|
||||
|
||||
.PHONY: cov cov-spin
|
||||
cov: misc/coverage.html
|
||||
cov-spin:
|
||||
make cov & bash misc/spin.sh $$!
|
||||
.PHONY: cov
|
||||
cov: misc/coverage.html ## Run coverage test
|
||||
|
||||
misc/coverage.html: $(TARGET) test.js
|
||||
mocha --require blanket -R html-cov -t 20000 > $@
|
||||
|
||||
.PHONY: coveralls coveralls-spin
|
||||
coveralls:
|
||||
mocha --require blanket --reporter mocha-lcov-reporter -t 20000 | ./node_modules/coveralls/bin/coveralls.js
|
||||
|
||||
coveralls-spin:
|
||||
make coveralls & bash misc/spin.sh $$!
|
||||
.PHONY: coveralls
|
||||
coveralls: ## Coverage Test + Send to coveralls.io
|
||||
mocha --require blanket --reporter mocha-lcov-reporter -t 20000 | node ./node_modules/coveralls/bin/coveralls.js
|
||||
|
||||
.PHONY: dist
|
||||
dist: dist-deps $(TARGET)
|
||||
dist: dist-deps $(TARGET) ## Prepare JS files for distribution
|
||||
cp $(TARGET) dist/
|
||||
cp LICENSE dist/
|
||||
uglifyjs $(TARGET) -o dist/$(LIB).min.js --source-map dist/$(LIB).min.map --preamble "$$(head -n 1 frac.js)"
|
||||
@ -65,16 +66,24 @@ dist-deps:
|
||||
## Python
|
||||
|
||||
.PHONY: pylint
|
||||
pylint: frac.py $(wildcard test_*.py)
|
||||
pylint: frac.py $(wildcard test_*.py) ## Run pep8 check
|
||||
pep8 $^
|
||||
|
||||
.PHONY: pypi
|
||||
pypi: frac.py
|
||||
pydist: frac.py ## Upload Python module to PyPI
|
||||
python setup.py sdist upload
|
||||
|
||||
.PHONY: pytest pypytest
|
||||
pytest: pylint
|
||||
pytest: pylint ## Run Python test suite
|
||||
py.test -v --durations=5
|
||||
|
||||
pypytest: pylint
|
||||
pypytest: pylint ## Run Python test suite in pypy
|
||||
pypy $$(which py.test) -v --durations=5
|
||||
|
||||
.PHONY: help
|
||||
help:
|
||||
@grep -hE '(^[a-zA-Z_-][ a-zA-Z_-]*:.*?|^#[#*])' $(MAKEFILE_LIST) | bash misc/help.sh
|
||||
|
||||
#* To show a spinner, append "-spin" to any target e.g. cov-spin
|
||||
%-spin:
|
||||
@make $* & bash misc/spin.sh $$!
|
||||
|
47
README.md
47
README.md
@ -7,17 +7,22 @@ Uses the [Mediant Method](https://en.wikipedia.org/wiki/Mediant_method).
|
||||
This module also provides an implementation of the continued fraction method as
|
||||
described by Aberth in "A method for exact computation with rational numbers".
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
### JS
|
||||
|
||||
With [npm](https://www.npmjs.org/package/frac):
|
||||
|
||||
$ npm install frac
|
||||
```bash
|
||||
$ npm install frac
|
||||
```
|
||||
|
||||
In the browser:
|
||||
|
||||
<script src="frac.js"></script>
|
||||
```html
|
||||
<script src="frac.js"></script>
|
||||
```
|
||||
|
||||
The script will manipulate `module.exports` if available (e.g. in a CommonJS
|
||||
`require` context). This is not always desirable. To prevent the behavior,
|
||||
@ -27,7 +32,9 @@ define `DO_NOT_EXPORT_FRAC`
|
||||
|
||||
From [PyPI](https://pypi.python.org/pypi/frac):
|
||||
|
||||
$ pip install frac
|
||||
```bash
|
||||
$ pip install frac
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
@ -67,33 +74,37 @@ For example:
|
||||
|
||||
`frac.med` implements Mediant method.
|
||||
|
||||
`frac.cont` implements Aberth algorithm
|
||||
`frac.cont` implements Aberth algorithm.
|
||||
|
||||
For example:
|
||||
|
||||
```py
|
||||
>>> import frac
|
||||
>>> frac.med(1.3, 9) # [ 0, 9, 7 ]
|
||||
>>> frac.med(1.3, 9, True) # [ 1, 2, 7 ]
|
||||
>>> frac.med(-1.3, 9) # [ 0, -9, 7 ]
|
||||
>>> frac.med(-1.3, 9, True) # [ -2, 5, 7 ]
|
||||
>>> frac.med(1.3, 9) ## [ 0, 9, 7 ] ## 1.3 ~ 9/7
|
||||
>>> frac.med(1.3, 9, True) ## [ 1, 2, 7 ] ## 1.3 ~ 1 + 2/7
|
||||
>>> frac.med(-1.3, 9) ## [ 0, -9, 7 ] ## -1.3 ~ -9/7
|
||||
>>> frac.med(-1.3, 9, True) ## [ -2, 5, 7 ] ## -1.3 ~ -2 + 5/7
|
||||
|
||||
>>> frac.cont(1.3, 9) # [ 0, 4, 3 ]
|
||||
>>> frac.cont(1.3, 9, True) # [ 1, 1, 3 ]
|
||||
>>> frac.cont(-1.3, 9) # [ 0, -4, 3 ]
|
||||
>>> frac.cont(-1.3, 9, True) # [ -2, 2, 3 ]
|
||||
>>> frac.cont(1.3, 9) ## [ 0, 4, 3 ] ## 1.3 ~ 4/3
|
||||
>>> frac.cont(1.3, 9, True) ## [ 1, 1, 3 ] ## 1.3 ~ 1 + 1/3
|
||||
>>> frac.cont(-1.3, 9) ## [ 0, -4, 3 ] ## -1.3 ~ -4/3
|
||||
>>> frac.cont(-1.3, 9, True) ## [ -2, 2, 3 ] ## -1.3 ~ -2 + 2/3
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
`make test` will run the node-based tests.
|
||||
|
||||
Tests generated from Excel have 4 columns. To produce a similar test:
|
||||
The test TSV baselines in the `test_files` directory have four columns:
|
||||
|
||||
- Column A contains the raw values
|
||||
- Column B format "Up to one digit (1/4)"
|
||||
- Column C format "Up to two digits (21/25)"
|
||||
- Column D format "Up to three digits (312/943)"
|
||||
- Column B format "Up to one digit (1/4)" (`denominator = 9`)
|
||||
- Column C format "Up to two digits (21/25)" (`denominator = 99`)
|
||||
- Column D format "Up to three digits (312/943)" (`denominator = 999`)
|
||||
|
||||
`make test` will run the node-based tests.
|
||||
|
||||
`make pytest` will run the python tests against the system Python version.
|
||||
|
||||
`make pypytest` will run the python tests against `pypy` if installed
|
||||
|
||||
## License
|
||||
|
||||
|
4
dist/frac.js
vendored
4
dist/frac.js
vendored
@ -1,5 +1,5 @@
|
||||
/* frac.js (C) 2012-present SheetJS -- http://sheetjs.com */
|
||||
var frac = function(x, D, mixed) {
|
||||
var frac = function frac(x, D, mixed) {
|
||||
var n1 = Math.floor(x), d1 = 1;
|
||||
var n2 = n1+1, d2 = 1;
|
||||
if(x !== n1) while(d1 <= D && d2 <= D) {
|
||||
@ -28,7 +28,7 @@ frac.cont = function cont(x, D, mixed) {
|
||||
A = Math.floor(B);
|
||||
P = A * P_1 + P_2;
|
||||
Q = A * Q_1 + Q_2;
|
||||
if((B - A) < 0.000000005) break;
|
||||
if((B - A) < 0.00000005) break;
|
||||
B = 1 / (B - A);
|
||||
P_2 = P_1; P_1 = P;
|
||||
Q_2 = Q_1; Q_1 = Q;
|
||||
|
3
dist/frac.min.js
vendored
3
dist/frac.min.js
vendored
@ -1 +1,2 @@
|
||||
var frac=function(x,D,mixed){var n1=Math.floor(x),d1=1;var n2=n1+1,d2=1;if(x!==n1)while(d1<=D&&d2<=D){var m=(n1+n2)/(d1+d2);if(x===m){if(d1+d2<=D){d1+=d2;n1+=n2;d2=D+1}else if(d1>d2)d2=D+1;else d1=D+1;break}else if(x<m){n2=n1+n2;d2=d1+d2}else{n1=n1+n2;d1=d1+d2}}if(d1>D){d1=d2;n1=n2}if(!mixed)return[0,n1,d1];var q=Math.floor(n1/d1);return[q,n1-q*d1,d1]};frac.cont=function cont(x,D,mixed){var sgn=x<0?-1:1;var B=x*sgn;var P_2=0,P_1=1,P=0;var Q_2=1,Q_1=0,Q=0;var A=Math.floor(B);while(Q_1<D){A=Math.floor(B);P=A*P_1+P_2;Q=A*Q_1+Q_2;if(B-A<5e-9)break;B=1/(B-A);P_2=P_1;P_1=P;Q_2=Q_1;Q_1=Q}if(Q>D){if(Q_1>D){Q=Q_2;P=P_2}else{Q=Q_1;P=P_1}}if(!mixed)return[0,sgn*P,Q];var q=Math.floor(sgn*P/Q);return[q,sgn*P-q*Q,Q]};if(typeof module!=="undefined"&&typeof DO_NOT_EXPORT_FRAC==="undefined")module.exports=frac;
|
||||
/* frac.js (C) 2012-present SheetJS -- http://sheetjs.com */
|
||||
var frac=function frac(x,D,mixed){var n1=Math.floor(x),d1=1;var n2=n1+1,d2=1;if(x!==n1)while(d1<=D&&d2<=D){var m=(n1+n2)/(d1+d2);if(x===m){if(d1+d2<=D){d1+=d2;n1+=n2;d2=D+1}else if(d1>d2)d2=D+1;else d1=D+1;break}else if(x<m){n2=n1+n2;d2=d1+d2}else{n1=n1+n2;d1=d1+d2}}if(d1>D){d1=d2;n1=n2}if(!mixed)return[0,n1,d1];var q=Math.floor(n1/d1);return[q,n1-q*d1,d1]};frac.cont=function cont(x,D,mixed){var sgn=x<0?-1:1;var B=x*sgn;var P_2=0,P_1=1,P=0;var Q_2=1,Q_1=0,Q=0;var A=Math.floor(B);while(Q_1<D){A=Math.floor(B);P=A*P_1+P_2;Q=A*Q_1+Q_2;if(B-A<5e-8)break;B=1/(B-A);P_2=P_1;P_1=P;Q_2=Q_1;Q_1=Q}if(Q>D){if(Q_1>D){Q=Q_2;P=P_2}else{Q=Q_1;P=P_1}}if(!mixed)return[0,sgn*P,Q];var q=Math.floor(sgn*P/Q);return[q,sgn*P-q*Q,Q]};if(typeof module!=="undefined"&&typeof DO_NOT_EXPORT_FRAC==="undefined")module.exports=frac;
|
||||
|
2
dist/frac.min.map
vendored
2
dist/frac.min.map
vendored
@ -1 +1 @@
|
||||
{"version":3,"file":"dist/frac.min.js","sources":["frac.js"],"names":["frac","x","D","mixed","n1","Math","floor","d1","n2","d2","m","q","cont","sgn","B","P_2","P_1","P","Q_2","Q_1","Q","A","module","DO_NOT_EXPORT_FRAC","exports"],"mappings":"AACA,GAAIA,MAAO,SAASC,EAAGC,EAAGC,OACxB,GAAIC,IAAKC,KAAKC,MAAML,GAAIM,GAAK,CAC7B,IAAIC,IAAKJ,GAAG,EAAGK,GAAK,CACpB,IAAGR,IAAMG,GAAI,MAAMG,IAAML,GAAKO,IAAMP,EAAG,CACrC,GAAIQ,IAAKN,GAAKI,KAAOD,GAAKE,GAC1B,IAAGR,IAAMS,EAAG,CACV,GAAGH,GAAKE,IAAMP,EAAG,CAAEK,IAAIE,EAAIL,KAAII,EAAIC,IAAGP,EAAE,MACnC,IAAGK,GAAKE,GAAIA,GAAGP,EAAE,MACjBK,IAAGL,EAAE,CACV,WAEG,IAAGD,EAAIS,EAAG,CAAEF,GAAKJ,GAAGI,EAAIC,IAAKF,GAAGE,OAChC,CAAEL,GAAKA,GAAGI,EAAID,IAAKA,GAAGE,IAE7B,GAAGF,GAAKL,EAAG,CAAEK,GAAKE,EAAIL,IAAKI,GAC3B,IAAIL,MAAO,OAAQ,EAAGC,GAAIG,GAC1B,IAAII,GAAIN,KAAKC,MAAMF,GAAGG,GACtB,QAAQI,EAAGP,GAAKO,EAAEJ,GAAIA,IAExBP,MAAKY,KAAO,QAASA,MAAKX,EAAGC,EAAGC,OAC9B,GAAIU,KAAMZ,EAAI,GAAK,EAAI,CACvB,IAAIa,GAAIb,EAAIY,GACZ,IAAIE,KAAM,EAAGC,IAAM,EAAGC,EAAI,CAC1B,IAAIC,KAAM,EAAGC,IAAM,EAAGC,EAAI,CAC1B,IAAIC,GAAIhB,KAAKC,MAAMQ,EACnB,OAAMK,IAAMjB,EAAG,CACbmB,EAAIhB,KAAKC,MAAMQ,EACfG,GAAII,EAAIL,IAAMD,GACdK,GAAIC,EAAIF,IAAMD,GACd,IAAIJ,EAAIO,EAAK,KAAa,KAC1BP,GAAI,GAAKA,EAAIO,EACbN,KAAMC,GAAKA,KAAMC,CACjBC,KAAMC,GAAKA,KAAMC,EAEnB,GAAGA,EAAIlB,EAAG,CAAE,GAAGiB,IAAMjB,EAAG,CAAEkB,EAAIF,GAAKD,GAAIF,QAAY,CAAEK,EAAID,GAAKF,GAAID,KAClE,IAAIb,MAAO,OAAQ,EAAGU,IAAMI,EAAGG,EAC/B,IAAIT,GAAIN,KAAKC,MAAMO,IAAMI,EAAEG,EAC3B,QAAQT,EAAGE,IAAII,EAAIN,EAAES,EAAGA,GAE1B,UAAUE,UAAW,mBAAsBC,sBAAuB,YAAaD,OAAOE,QAAUxB"}
|
||||
{"version":3,"sources":["frac.js"],"names":["frac","x","D","mixed","n1","Math","floor","d1","n2","d2","m","q","cont","sgn","B","P_2","P_1","P","Q_2","Q_1","Q","A","module","DO_NOT_EXPORT_FRAC","exports"],"mappings":";AACA,GAAIA,MAAO,QAASA,MAAKC,EAAGC,EAAGC,OAC7B,GAAIC,IAAKC,KAAKC,MAAML,GAAIM,GAAK,CAC7B,IAAIC,IAAKJ,GAAG,EAAGK,GAAK,CACpB,IAAGR,IAAMG,GAAI,MAAMG,IAAML,GAAKO,IAAMP,EAAG,CACrC,GAAIQ,IAAKN,GAAKI,KAAOD,GAAKE,GAC1B,IAAGR,IAAMS,EAAG,CACV,GAAGH,GAAKE,IAAMP,EAAG,CAAEK,IAAIE,EAAIL,KAAII,EAAIC,IAAGP,EAAE,MACnC,IAAGK,GAAKE,GAAIA,GAAGP,EAAE,MACjBK,IAAGL,EAAE,CACV,WAEG,IAAGD,EAAIS,EAAG,CAAEF,GAAKJ,GAAGI,EAAIC,IAAKF,GAAGE,OAChC,CAAEL,GAAKA,GAAGI,EAAID,IAAKA,GAAGE,IAE7B,GAAGF,GAAKL,EAAG,CAAEK,GAAKE,EAAIL,IAAKI,GAC3B,IAAIL,MAAO,OAAQ,EAAGC,GAAIG,GAC1B,IAAII,GAAIN,KAAKC,MAAMF,GAAGG,GACtB,QAAQI,EAAGP,GAAKO,EAAEJ,GAAIA,IAExBP,MAAKY,KAAO,QAASA,MAAKX,EAAGC,EAAGC,OAC9B,GAAIU,KAAMZ,EAAI,GAAK,EAAI,CACvB,IAAIa,GAAIb,EAAIY,GACZ,IAAIE,KAAM,EAAGC,IAAM,EAAGC,EAAI,CAC1B,IAAIC,KAAM,EAAGC,IAAM,EAAGC,EAAI,CAC1B,IAAIC,GAAIhB,KAAKC,MAAMQ,EACnB,OAAMK,IAAMjB,EAAG,CACbmB,EAAIhB,KAAKC,MAAMQ,EACfG,GAAII,EAAIL,IAAMD,GACdK,GAAIC,EAAIF,IAAMD,GACd,IAAIJ,EAAIO,EAAK,KAAY,KACzBP,GAAI,GAAKA,EAAIO,EACbN,KAAMC,GAAKA,KAAMC,CACjBC,KAAMC,GAAKA,KAAMC,EAEnB,GAAGA,EAAIlB,EAAG,CAAE,GAAGiB,IAAMjB,EAAG,CAAEkB,EAAIF,GAAKD,GAAIF,QAAY,CAAEK,EAAID,GAAKF,GAAID,KAClE,IAAIb,MAAO,OAAQ,EAAGU,IAAMI,EAAGG,EAC/B,IAAIT,GAAIN,KAAKC,MAAMO,IAAMI,EAAEG,EAC3B,QAAQT,EAAGE,IAAII,EAAIN,EAAES,EAAGA,GAE1B,UAAUE,UAAW,mBAAsBC,sBAAuB,YAAaD,OAAOE,QAAUxB","file":"dist/frac.min.js"}
|
@ -1,5 +1,5 @@
|
||||
/* frac.js (C) 2012-present SheetJS -- http://sheetjs.com */
|
||||
var frac = function(x/*:number*/, D/*:number*/, mixed/*:?boolean*/)/*:Array<number>*/ {
|
||||
var frac = function frac(x/*:number*/, D/*:number*/, mixed/*:?boolean*/)/*:Array<number>*/ {
|
||||
var n1 = Math.floor(x), d1 = 1;
|
||||
var n2 = n1+1, d2 = 1;
|
||||
if(x !== n1) while(d1 <= D && d2 <= D) {
|
||||
@ -28,7 +28,7 @@ frac.cont = function cont(x/*:number*/, D/*:number*/, mixed/*:?boolean*/)/*:Arra
|
||||
A = Math.floor(B);
|
||||
P = A * P_1 + P_2;
|
||||
Q = A * Q_1 + Q_2;
|
||||
if((B - A) < 0.000000005) break;
|
||||
if((B - A) < 0.00000005) break;
|
||||
B = 1 / (B - A);
|
||||
P_2 = P_1; P_1 = P;
|
||||
Q_2 = Q_1; Q_1 = Q;
|
||||
|
4
frac.js
4
frac.js
@ -1,5 +1,5 @@
|
||||
/* frac.js (C) 2012-present SheetJS -- http://sheetjs.com */
|
||||
var frac = function(x, D, mixed) {
|
||||
var frac = function frac(x, D, mixed) {
|
||||
var n1 = Math.floor(x), d1 = 1;
|
||||
var n2 = n1+1, d2 = 1;
|
||||
if(x !== n1) while(d1 <= D && d2 <= D) {
|
||||
@ -28,7 +28,7 @@ frac.cont = function cont(x, D, mixed) {
|
||||
A = Math.floor(B);
|
||||
P = A * P_1 + P_2;
|
||||
Q = A * Q_1 + Q_2;
|
||||
if((B - A) < 0.000000005) break;
|
||||
if((B - A) < 0.00000005) break;
|
||||
B = 1 / (B - A);
|
||||
P_2 = P_1; P_1 = P;
|
||||
Q_2 = Q_1; Q_1 = Q;
|
||||
|
46
frac.md
46
frac.md
@ -23,7 +23,7 @@ that behavior, pass the absolute value to frac and prepend a "-" if negative.
|
||||
|
||||
```js>frac.flow.js
|
||||
/* frac.js (C) 2012-present SheetJS -- http://sheetjs.com */
|
||||
var frac = function(x/*:number*/, D/*:number*/, mixed/*:?boolean*/)/*:Array<number>*/ {
|
||||
var frac = function frac(x/*:number*/, D/*:number*/, mixed/*:?boolean*/)/*:Array<number>*/ {
|
||||
```
|
||||
|
||||
The goal is to maintain a feasible fraction (with bounded denominator) below
|
||||
@ -91,7 +91,7 @@ to the desired goal of most accurately approximating the floating point number)
|
||||
frac.cont = function cont(x/*:number*/, D/*:number*/, mixed/*:?boolean*/)/*:Array<number>*/ {
|
||||
```
|
||||
|
||||
> Record the sign of x, take b0=|x|, p_{-2}=0, p_{-1}=1, q_{-2}=1, q_{-1}=0
|
||||
> Record the sign of x, take `b0=|x|, p_{-2}=0, p_{-1}=1, q_{-2}=1, q_{-1}=0`
|
||||
|
||||
Note that the variables are implicitly indexed at `k` (so `B` refers to `b_k`):
|
||||
|
||||
@ -102,8 +102,8 @@ Note that the variables are implicitly indexed at `k` (so `B` refers to `b_k`):
|
||||
var Q_2 = 1, Q_1 = 0, Q = 0;
|
||||
```
|
||||
|
||||
`A` should be the floor of `B`. Originally the bit-or trick was used, but this is not correct
|
||||
for the range `B>=2**32`.
|
||||
`A` should be the floor of `B`. Originally the bit-or trick was used, but this
|
||||
is not correct for the range `B>=2**32`.
|
||||
|
||||
```
|
||||
var A = Math.floor(B);
|
||||
@ -111,31 +111,31 @@ for the range `B>=2**32`.
|
||||
|
||||
> Iterate
|
||||
|
||||
> ... for k = 0,1,...,K, where K is the first instance of k where
|
||||
> either q_{k+1} > Q or b_{k+1} is undefined (b_k = a_k).
|
||||
> ... for `k = 0,1,...,K`, where `K` is the first instance of `k` where
|
||||
> either `q_{k+1} > Q` or `b_{k+1}` is undefined (`b_k = a_k`).
|
||||
|
||||
```
|
||||
while(Q_1 < D) {
|
||||
```
|
||||
|
||||
> a_k = [b_k], i.e., the greatest integer <= b_k
|
||||
> `a_k = [b_k]`, i.e., the greatest integer `<= b_k`
|
||||
|
||||
```
|
||||
A = Math.floor(B);
|
||||
```
|
||||
|
||||
> p_k = a_k p_{k-1} + p_{k-2}
|
||||
> q_k = a_k q_{k-1} + q_{k-2}
|
||||
> `p_k = a_k p_{k-1} + p_{k-2}`
|
||||
> `q_k = a_k q_{k-1} + q_{k-2}`
|
||||
|
||||
```
|
||||
P = A * P_1 + P_2;
|
||||
Q = A * Q_1 + Q_2;
|
||||
```
|
||||
|
||||
> b_{k+1} = (b_{k} - a_{k})^{-1}
|
||||
> `b_{k+1} = (b_{k} - a_{k})^{-1}`
|
||||
|
||||
```
|
||||
if((B - A) < 0.000000005) break;
|
||||
if((B - A) < 0.00000005) break;
|
||||
```
|
||||
|
||||
At the end of each iteration, advance `k` by one step:
|
||||
@ -184,21 +184,25 @@ var xltestfiles=[
|
||||
];
|
||||
|
||||
function xlline(o,j,m,w) {
|
||||
it(j, function() {
|
||||
var d, q, qq;
|
||||
it(j.toString(), function() {
|
||||
var d, q, qq, f = 0.1;
|
||||
var q0 = 0, q1 = 0, q2 = 0
|
||||
for(var i = j*w; i < m-3 && i < (j+1)*w; ++i) {
|
||||
d = o[i].split("\t");
|
||||
if(d.length < 3) continue;
|
||||
f = parseFloat(d[0]);
|
||||
|
||||
q = frac.cont(Number(d[0]), 9, true);
|
||||
qq = (q[0]||q[1]) ? (q[0] || "") + " " + (q[1] ? q[1] + "/" + q[2] : " ") : "0 ";
|
||||
q = frac.cont(f, 9, true);
|
||||
q0 = q[0]; q1 = q[1]; q2 = q[2];
|
||||
qq = (q0!=0||q1!=0) ? (q0!=0 ? q0.toString() : "") + " " + (q1!=0 ? q1.toString() + "/" + q2.toString() : " ") : "0 ";
|
||||
assert.equal(qq, d[1], d[1] + " 1");
|
||||
|
||||
q = frac.cont(Number(d[0]), 99, true);
|
||||
qq = (q[0]||q[1]) ? (q[0] || "") + " " + (q[1] ? (q[1] < 10 ? " " : "") + q[1] + "/" + q[2] + (q[2]<10?" ":"") : " ") : "0 ";
|
||||
q = frac.cont(f, 99, true);
|
||||
qq = (q[0]!=0||q[1]!=0) ? (q[0]!=0 ? q[0].toString() : "") + " " + (q[1]!=0 ? (q[1] < 10 ? " " : "") + q[1].toString() + "/" + q[2].toString() + (q[2]<10?" ":"") : " ") : "0 ";
|
||||
assert.equal(qq, d[2], d[2] + " 2");
|
||||
|
||||
q = frac.cont(Number(d[0]), 999, true);
|
||||
qq = (q[0]||q[1]) ? (q[0] || "") + " " + (q[1] ? (q[1] < 100 ? " " : "") + (q[1] < 10 ? " " : "") + q[1] + "/" + q[2] + (q[2]<10?" ":"") + (q[2]<100?" ":""): " ") : "0 ";
|
||||
q = frac.cont(f, 999, true);
|
||||
qq = (q[0]!=0||q[1]!=0) ? (q[0]!=0 ? q[0].toString() : "") + " " + (q[1]!=0 ? (q[1] < 100 ? " " : "") + (q[1] < 10 ? " " : "") + q[1].toString() + "/" + q[2].toString() + (q[2]<10?" ":"") + (q[2]<100?" ":""): " ") : "0 ";
|
||||
assert.equal(qq, d[3], d[3] + " 3");
|
||||
}
|
||||
});
|
||||
@ -239,7 +243,7 @@ xltestfiles.forEach(function(x) {
|
||||
```json>package.json
|
||||
{
|
||||
"name": "frac",
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.5",
|
||||
"author": "SheetJS",
|
||||
"description": "Rational approximation with bounded denominator",
|
||||
"keywords": [ "math", "fraction", "rational", "approximation" ],
|
||||
@ -252,7 +256,7 @@ xltestfiles.forEach(function(x) {
|
||||
},
|
||||
"repository": { "type":"git", "url":"git://github.com/SheetJS/frac.git" },
|
||||
"scripts": {
|
||||
"test": "mocha -R spec"
|
||||
"test": "make test"
|
||||
},
|
||||
"config": {
|
||||
"blanket": {
|
||||
|
2
frac.py
2
frac.py
@ -55,7 +55,7 @@ def cont(x, D, mixed=False):
|
||||
A = I(B)
|
||||
P = A * P_1 + P_2
|
||||
Q = A * Q_1 + Q_2
|
||||
if (B - A) < 0.0000000005:
|
||||
if (B - A) < 0.00000005:
|
||||
break
|
||||
B = 1. / (B-A)
|
||||
P_2, P_1 = P_1, P
|
||||
|
@ -21,6 +21,7 @@
|
||||
</table>
|
||||
</body>
|
||||
<script>
|
||||
/*jshint browser:true */
|
||||
var V = document.getElementById('val');
|
||||
var F = document.getElementById('fmt');
|
||||
var X = document.getElementById('mix');
|
||||
|
42
misc/help.sh
Executable file
42
misc/help.sh
Executable file
@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
# make_help.sh -- process listing of targets and special items in Makefile
|
||||
# Copyright (C) 2016-present SheetJS
|
||||
#
|
||||
# usage in makefile: pipe the output of the following command:
|
||||
# @grep -hE '(^[a-zA-Z_-][ a-zA-Z_-]*:.*?|^#[#*])' $(MAKEFILE_LIST)
|
||||
#
|
||||
# lines starting with "## " are treated as subtitles
|
||||
# lines starting with "#* " are treated as plaintext comments
|
||||
# multiple targets with "## " after the ":" are rendered as separate targets
|
||||
# if the presumed default target is labeled, it will be assigned a unique color
|
||||
|
||||
awk '
|
||||
BEGIN{recipes=0;}
|
||||
!/#[#*] .*$/ {next;}
|
||||
{multi=0; isrecipe=0;}
|
||||
/^[^#]*:/ {isrecipe=1; ++recipes;}
|
||||
/^[^ :]* .*:/ {multi=1}
|
||||
multi==0 && isrecipe>0 { if(recipes > 1) print; else print $0, "[default]"; next}
|
||||
isrecipe == 0 {print; next}
|
||||
multi>0 {
|
||||
k=split($0, msg, "##"); m=split($0, a, ":"); n=split(a[1], b, " ");
|
||||
for(i=1; i<=n; ++i) print b[i] ":", "##" msg[2], (recipes==1 && i==1 ? "[default]" : "")
|
||||
}
|
||||
END {}
|
||||
' | if [[ -t 1 ]]; then
|
||||
awk '
|
||||
BEGIN {FS = ":.*?## "}
|
||||
{color=36}
|
||||
/\[default\]/ {color=35}
|
||||
NF==1 && /^##/ {color=34}
|
||||
NF==1 && /^#\*/ {color=20; $1 = substr($1, 4)}
|
||||
{printf "\033[" color "m%-20s\033[0m %s\n", $1, $2;}
|
||||
END{}' -
|
||||
else
|
||||
awk '
|
||||
BEGIN {FS = ":.*?## "}
|
||||
/^#\* / {$1 = substr($1, 4)}
|
||||
{printf "%-20s %s\n", $1, $2;}
|
||||
END{}' -
|
||||
fi
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "frac",
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.5",
|
||||
"author": "SheetJS",
|
||||
"description": "Rational approximation with bounded denominator",
|
||||
"keywords": [ "math", "fraction", "rational", "approximation" ],
|
||||
@ -13,7 +13,7 @@
|
||||
},
|
||||
"repository": { "type":"git", "url":"git://github.com/SheetJS/frac.git" },
|
||||
"scripts": {
|
||||
"test": "mocha -R spec"
|
||||
"test": "make test"
|
||||
},
|
||||
"config": {
|
||||
"blanket": {
|
||||
|
2
setup.py
2
setup.py
@ -1,7 +1,7 @@
|
||||
from distutils.core import setup
|
||||
setup(
|
||||
name='frac',
|
||||
version='1.0.2',
|
||||
version='1.0.5',
|
||||
author='SheetJS',
|
||||
author_email='dev@sheetjs.com',
|
||||
url='http://oss.sheetjs.com/frac',
|
||||
|
20
test.js
20
test.js
@ -10,21 +10,25 @@ var xltestfiles=[
|
||||
];
|
||||
|
||||
function xlline(o,j,m,w) {
|
||||
it(j, function() {
|
||||
var d, q, qq;
|
||||
it(j.toString(), function() {
|
||||
var d, q, qq, f = 0.1;
|
||||
var q0 = 0, q1 = 0, q2 = 0
|
||||
for(var i = j*w; i < m-3 && i < (j+1)*w; ++i) {
|
||||
d = o[i].split("\t");
|
||||
if(d.length < 3) continue;
|
||||
f = parseFloat(d[0]);
|
||||
|
||||
q = frac.cont(Number(d[0]), 9, true);
|
||||
qq = (q[0]||q[1]) ? (q[0] || "") + " " + (q[1] ? q[1] + "/" + q[2] : " ") : "0 ";
|
||||
q = frac.cont(f, 9, true);
|
||||
q0 = q[0]; q1 = q[1]; q2 = q[2];
|
||||
qq = (q0!=0||q1!=0) ? (q0!=0 ? q0.toString() : "") + " " + (q1!=0 ? q1.toString() + "/" + q2.toString() : " ") : "0 ";
|
||||
assert.equal(qq, d[1], d[1] + " 1");
|
||||
|
||||
q = frac.cont(Number(d[0]), 99, true);
|
||||
qq = (q[0]||q[1]) ? (q[0] || "") + " " + (q[1] ? (q[1] < 10 ? " " : "") + q[1] + "/" + q[2] + (q[2]<10?" ":"") : " ") : "0 ";
|
||||
q = frac.cont(f, 99, true);
|
||||
qq = (q[0]!=0||q[1]!=0) ? (q[0]!=0 ? q[0].toString() : "") + " " + (q[1]!=0 ? (q[1] < 10 ? " " : "") + q[1].toString() + "/" + q[2].toString() + (q[2]<10?" ":"") : " ") : "0 ";
|
||||
assert.equal(qq, d[2], d[2] + " 2");
|
||||
|
||||
q = frac.cont(Number(d[0]), 999, true);
|
||||
qq = (q[0]||q[1]) ? (q[0] || "") + " " + (q[1] ? (q[1] < 100 ? " " : "") + (q[1] < 10 ? " " : "") + q[1] + "/" + q[2] + (q[2]<10?" ":"") + (q[2]<100?" ":""): " ") : "0 ";
|
||||
q = frac.cont(f, 999, true);
|
||||
qq = (q[0]!=0||q[1]!=0) ? (q[0]!=0 ? q[0].toString() : "") + " " + (q[1]!=0 ? (q[1] < 100 ? " " : "") + (q[1] < 10 ? " " : "") + q[1].toString() + "/" + q[2].toString() + (q[2]<10?" ":"") + (q[2]<100?" ":""): " ") : "0 ";
|
||||
assert.equal(qq, d[3], d[3] + " 3");
|
||||
}
|
||||
});
|
||||
|
@ -123,4 +123,3 @@
|
||||
1234567892.2 1234567892 1/5 1234567892 1/5 1234567892 1/5
|
||||
1234567892.3 1234567892 2/7 1234567892 3/10 1234567892 3/10
|
||||
1234567892.4 1234567892 2/5 1234567892 2/5 1234567892 2/5
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user