version bump 1.0.1: cleanup and python
- demo page (gh-pages branch) - updated year - flow annotations in separate frac.flow.js file - introduced build infrastructure from js-xlsx - python version
This commit is contained in:
		
							parent
							
								
									5ed8c61d24
								
							
						
					
					
						commit
						2f54d2f5c1
					
				
							
								
								
									
										12
									
								
								.flowconfig
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										12
									
								
								.flowconfig
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| [ignore] | ||||
| .*/node_modules/.* | ||||
| .*/dist/.* | ||||
| .*/test.js | ||||
| .*/frac.js | ||||
| 
 | ||||
| [include] | ||||
| frac.flow.js | ||||
| 
 | ||||
| [libs] | ||||
| 
 | ||||
| [options] | ||||
							
								
								
									
										6
									
								
								.jscs.json
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										6
									
								
								.jscs.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | ||||
| { | ||||
|   "requireCommaBeforeLineBreak": true, | ||||
|   "disallowTrailingWhitespace": true, | ||||
|   "disallowTrailingComma": true | ||||
| } | ||||
| 
 | ||||
							
								
								
									
										4
									
								
								.jshintrc
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										4
									
								
								.jshintrc
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | ||||
| { | ||||
| 	"bitwise": false, | ||||
| 	"curly": false | ||||
| } | ||||
							
								
								
									
										11
									
								
								.npmignore
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										11
									
								
								.npmignore
									
									
									
									
									
								
							| @ -2,3 +2,14 @@ test_files/*.tsv | ||||
| .gitignore | ||||
| node_modules/ | ||||
| coverage.html | ||||
| .travis.yml | ||||
| .jshintrc | ||||
| .jscs.json | ||||
| .flowconfig | ||||
| misc/ | ||||
| *.sheetjs | ||||
| *.pyc | ||||
| build/ | ||||
| MANIFEST | ||||
| *.gz | ||||
| *.tgz | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| language: node_js | ||||
| node_js: | ||||
|   - "iojs" | ||||
|   - "0.10" | ||||
|   - "0.8" | ||||
| before_install: | ||||
| @ -7,4 +8,4 @@ before_install: | ||||
|   - "npm install blanket" | ||||
|   - "npm install coveralls mocha-lcov-reporter" | ||||
| after_success: | ||||
|   - "make coveralls" | ||||
|   - "make coveralls-spin" | ||||
|  | ||||
							
								
								
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								LICENSE
									
									
									
									
									
								
							| @ -1,4 +1,4 @@ | ||||
| Copyright (C) 2012-2014   SheetJS | ||||
| Copyright (C) 2012-2015   SheetJS | ||||
| 
 | ||||
|    Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|    you may not use this file except in compliance with the License. | ||||
|  | ||||
							
								
								
									
										77
									
								
								Makefile
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										77
									
								
								Makefile
									
									
									
									
									
								
							| @ -1,29 +1,74 @@ | ||||
| LIB=frac | ||||
| TARGET=$(LIB).js | ||||
| .PHONY: frac | ||||
| frac: frac.md | ||||
| 	voc frac.md | ||||
| REQS= | ||||
| ADDONS= | ||||
| AUXTARGETS= | ||||
| 
 | ||||
| .PHONY: test | ||||
| test: | ||||
| 	mocha -R spec | ||||
| ULIB=$(shell echo $(LIB) | tr a-z A-Z) | ||||
| DEPS=$(LIB).md | ||||
| TARGET=$(LIB).js | ||||
| 
 | ||||
| .PHONY: all | ||||
| all: $(TARGET) $(AUXTARGETS) | ||||
| 
 | ||||
| $(TARGET) $(AUXTARGETS): %.js : %.flow.js | ||||
| 	node -e 'process.stdout.write(require("fs").readFileSync("$<","utf8").replace(/^\s*\/\*:[^*]*\*\/\s*(\n)?/gm,"").replace(/\/\*:[^*]*\*\//gm,""))' > $@ | ||||
| 
 | ||||
| $(LIB).flow.js: $(DEPS) | ||||
| 	voc $^ | ||||
| 
 | ||||
| .PHONY: clean | ||||
| clean: | ||||
| 	rm -f $(TARGET) | ||||
| 
 | ||||
| 
 | ||||
| .PHONY: test mocha | ||||
| test mocha: test.js | ||||
| 	mocha -R spec -t 20000 | ||||
| 
 | ||||
| .PHONY: lint | ||||
| lint: | ||||
| 	jshint --show-non-errors frac.js | ||||
| lint: $(TARGET) $(AUXTARGETS) | ||||
| 	jshint --show-non-errors $(TARGET) $(AUXTARGETS) | ||||
| 	jshint --show-non-errors package.json | ||||
| 	jscs $(TARGET) $(AUXTARGETS) | ||||
| 
 | ||||
| .PHONY: cov | ||||
| cov: coverage.html | ||||
| .PHONY: flow | ||||
| flow: lint | ||||
| 	flow check --all --show-all-errors | ||||
| 
 | ||||
| coverage.html: frac | ||||
| 	mocha --require blanket -R html-cov > coverage.html | ||||
| .PHONY: cov cov-spin | ||||
| cov: misc/coverage.html | ||||
| cov-spin: | ||||
| 	make cov & bash misc/spin.sh $$! | ||||
| 
 | ||||
| .PHONY: coveralls | ||||
| 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 | ./node_modules/coveralls/bin/coveralls.js | ||||
| 	mocha --require blanket --reporter mocha-lcov-reporter -t 20000 | ./node_modules/coveralls/bin/coveralls.js | ||||
| 
 | ||||
| coveralls-spin: | ||||
| 	make coveralls & bash misc/spin.sh $$! | ||||
| 
 | ||||
| .PHONY: dist | ||||
| dist: $(TARGET) | ||||
| dist: dist-deps $(TARGET) | ||||
| 	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)" | ||||
| 	misc/strip_sourcemap.sh dist/$(LIB).min.js | ||||
| 
 | ||||
| .PHONY: aux | ||||
| aux: $(AUXTARGETS) | ||||
| .PHONY: dist-deps | ||||
| dist-deps: | ||||
| 
 | ||||
| ## Python
 | ||||
| 
 | ||||
| .PHONY: pylint | ||||
| pylint: frac.py | ||||
| 	pep8 $^ | ||||
| 
 | ||||
| .PHONY: pypi | ||||
| pypi: frac.py | ||||
| 	python setup.py sdist upload | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										1
									
								
								README
									
									
									
									
									
										Symbolic link
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										1
									
								
								README
									
									
									
									
									
										Symbolic link
									
								
							| @ -0,0 +1 @@ | ||||
| README.md | ||||
							
								
								
									
										36
									
								
								README.md
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										36
									
								
								README.md
									
									
									
									
									
								
							| @ -2,15 +2,14 @@ | ||||
| 
 | ||||
| Rational approximation to a floating point number with bounded denominator. | ||||
| 
 | ||||
| Uses the Mediant Method <https://en.wikipedia.org/wiki/Mediant_(mathematics)> | ||||
| 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", | ||||
| which appears to be used by spreadsheet programs for displaying fractions | ||||
| described by Aberth in "A method for exact computation with rational numbers". | ||||
| 
 | ||||
| ## Setup | ||||
| ## Installation | ||||
| 
 | ||||
| In node: | ||||
| With [npm](https://www.npmjs.org/package/frac): | ||||
| 
 | ||||
|     $ npm install frac | ||||
| 
 | ||||
| @ -28,27 +27,28 @@ The exported `frac` function takes three arguments: | ||||
| 
 | ||||
|  - `x` the number we wish to approximate | ||||
|  - `D` the maximum denominator | ||||
|  - `mixed` if true, return a mixed fraction (default); if false, improper | ||||
|  - `mixed` if true, return a mixed fraction; if false, improper | ||||
| 
 | ||||
| The return value is an array of the form `[quot, num, den]` where `quot==0` | ||||
| for improper fractions. | ||||
| for improper fractions.  `quot <= x` for mixed fractions, which may lead to some | ||||
| unexpected results when rendering negative numbers. | ||||
| 
 | ||||
| For example: | ||||
| 
 | ||||
| ``` | ||||
| > // var frac = require('frac'); // uncomment this line if in node | ||||
| > frac(Math.PI,100) // [ 0, 22, 7 ] | ||||
| > frac(Math.PI,100,true) // [ 3, 1, 7 ] | ||||
| > frac(Math.PI,100); // [ 0, 22, 7 ] | ||||
| > frac(Math.PI,100,true); // [ 3, 1, 7 ] | ||||
| > frac(-Math.PI,100); // [ 0, -22, 7 ] | ||||
| > frac(-Math.PI,100,true); // [ -4, 6, 7 ] // the approximation is (-4) + (6/7) | ||||
| ``` | ||||
| 
 | ||||
| `frac.cont` implements the Aberth algorithm (input and output specifications | ||||
| match the original `frac` function) | ||||
| 
 | ||||
| ## License | ||||
| ## Testing | ||||
| 
 | ||||
| Apache 2.0 | ||||
| 
 | ||||
| ## Tests | ||||
| `make test` will run the node-based tests. | ||||
| 
 | ||||
| Tests generated from Excel have 4 columns.  To produce a similar test: | ||||
| 
 | ||||
| @ -57,9 +57,15 @@ Tests generated from Excel have 4 columns.  To produce a similar test: | ||||
| - Column C format "Up to two digits (21/25)" | ||||
| - Column D format "Up to three digits (312/943)" | ||||
| 
 | ||||
| ## License | ||||
| 
 | ||||
| Please consult the attached LICENSE file for details.  All rights not explicitly | ||||
| granted by the Apache 2.0 license are reserved by the Original Author. | ||||
| 
 | ||||
| ## Badges | ||||
| 
 | ||||
| [](https://travis-ci.org/SheetJS/frac) | ||||
| 
 | ||||
| [](https://coveralls.io/r/SheetJS/frac?branch=master) | ||||
| [](https://coveralls.io/r/SheetJS/frac?branch=master) | ||||
| 
 | ||||
| [](http://githalytics.com/SheetJS/frac) | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										2
									
								
								dist/LICENSE
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/LICENSE
									
									
									
									
										vendored
									
									
								
							| @ -1,4 +1,4 @@ | ||||
| Copyright (C) 2012-2014   SheetJS | ||||
| Copyright (C) 2012-2015   SheetJS | ||||
| 
 | ||||
|    Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|    you may not use this file except in compliance with the License. | ||||
|  | ||||
							
								
								
									
										2
									
								
								dist/frac.js
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								dist/frac.js
									
									
									
									
										vendored
									
									
								
							| @ -1,4 +1,4 @@ | ||||
| /* frac.js (C) 2012-2014 SheetJS -- http://sheetjs.com */ | ||||
| /* frac.js (C) 2012-2015 SheetJS -- http://sheetjs.com */ | ||||
| var frac = function(x, D, mixed) { | ||||
|   var n1 = Math.floor(x), d1 = 1; | ||||
|   var n2 = n1+1, d2 = 1; | ||||
|  | ||||
							
								
								
									
										3
									
								
								dist/frac.min.js
									
									
									
									
										vendored
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										3
									
								
								dist/frac.min.js
									
									
									
									
										vendored
									
									
								
							| @ -1,3 +1,2 @@ | ||||
| /* frac.js (C) 2012-2014 SheetJS -- http://sheetjs.com */ | ||||
| /* frac.js (C) 2012-2015 SheetJS -- http://sheetjs.com */ | ||||
| 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-10)break;B=1/(B-A);P_2=P_1;P_1=P;Q_2=Q_1;Q_1=Q}if(Q>D){Q=Q_1;P=P_1}if(Q>D){Q=Q_2;P=P_2}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; | ||||
| //# sourceMappingURL=dist/frac.min.map
 | ||||
							
								
								
									
										43
									
								
								frac.flow.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										43
									
								
								frac.flow.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| /* frac.js (C) 2012-2015 SheetJS -- http://sheetjs.com */ | ||||
| var frac = function(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) { | ||||
|     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/*:number*/, D/*:number*/, mixed/*:?boolean*/)/*:Array<number>*/ { | ||||
|   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) < 0.0000000005) break; | ||||
|     B = 1 / (B - A); | ||||
|     P_2 = P_1; P_1 = P; | ||||
|     Q_2 = Q_1; Q_1 = Q; | ||||
|   } | ||||
|   if(Q > D) { Q = Q_1; P = P_1; } | ||||
|   if(Q > D) { Q = Q_2; P = P_2; } | ||||
|   if(!mixed) return [0, sgn * P, Q]; | ||||
|   var q = Math.floor(sgn * P/Q); | ||||
|   return [q, sgn*P - q*Q, Q]; | ||||
| }; | ||||
| /*:: declare var DO_NOT_EXPORT_FRAC: any; */ | ||||
| if(typeof module !== 'undefined' && typeof DO_NOT_EXPORT_FRAC === 'undefined') module.exports = frac; | ||||
							
								
								
									
										2
									
								
								frac.js
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										2
									
								
								frac.js
									
									
									
									
									
								
							| @ -1,4 +1,4 @@ | ||||
| /* frac.js (C) 2012-2014 SheetJS -- http://sheetjs.com */ | ||||
| /* frac.js (C) 2012-2015 SheetJS -- http://sheetjs.com */ | ||||
| var frac = function(x, D, mixed) { | ||||
|   var n1 = Math.floor(x), d1 = 1; | ||||
|   var n2 = n1+1, d2 = 1; | ||||
|  | ||||
							
								
								
									
										46
									
								
								frac.md
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										46
									
								
								frac.md
									
									
									
									
									
								
							| @ -4,20 +4,26 @@ In all languages, the target is a function that takes 3 parameters: | ||||
| 
 | ||||
|  - `x` the number we wish to approximate | ||||
|  - `D` the maximum denominator | ||||
|  - `mixed` if true, return a mixed fraction (default); if false, improper | ||||
|  - `mixed` if true, return a mixed fraction; if false, improper | ||||
| 
 | ||||
| The JS implementation walks through the algorithm. | ||||
| 
 | ||||
| # JS Implementation | ||||
| 
 | ||||
| In this version, the return value is `[quotient, numerator, denominator]`, | ||||
| where `quotient == 0` for improper fractions. The interpretation is | ||||
| `x ~ quotient + numerator / denominator` where `0 <= numerator < denominator` | ||||
| and `quotient <= x` for negative `x`. | ||||
| In this version, the return value is `[quotient, numerator, denominator]`.  The | ||||
| interpretation is `x ~ quotient + numerator / denominator` | ||||
| 
 | ||||
| ```js>frac.js | ||||
| /* frac.js (C) 2012-2014 SheetJS -- http://sheetjs.com */ | ||||
| var frac = function(x, D, mixed) { | ||||
| - For improper fractions, `quotient == 0`. | ||||
| 
 | ||||
| - For proper fractions, `0 <= numerator < denominator` and `quotient <= x` | ||||
| 
 | ||||
| For negative `x`, this deviates from how some people and systems interpret mixed | ||||
| fractions.  Some interpret `a b/c` as `sgn(a) * [abs(a) + b/c]`.  To replicate | ||||
| that behavior, pass the absolute value to frac and prepend a "-" if negative. | ||||
| 
 | ||||
| ```js>frac.flow.js | ||||
| /* frac.js (C) 2012-2015 SheetJS -- http://sheetjs.com */ | ||||
| var frac = function(x/*:number*/, D/*:number*/, mixed/*:?boolean*/)/*:Array<number>*/ { | ||||
| ``` | ||||
| 
 | ||||
| The goal is to maintain a feasible fraction (with bounded denominator) below | ||||
| @ -81,8 +87,8 @@ The continued fraction technique is employed by various spreadsheet programs. | ||||
| Note that this technique is inferior to the mediant method (at least, according | ||||
| to the desired goal of most accurately approximating the floating point number) | ||||
| 
 | ||||
| ``` | ||||
| frac.cont = function cont(x, D, mixed) { | ||||
| ```js>frac.flow.js | ||||
| 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 | ||||
| @ -160,6 +166,7 @@ The final result is `r = (sgn x)p_k / q_k`: | ||||
| Finally we put some export jazz: | ||||
| 
 | ||||
| ``` | ||||
| /*:: declare var DO_NOT_EXPORT_FRAC: any; */ | ||||
| if(typeof module !== 'undefined' && typeof DO_NOT_EXPORT_FRAC === 'undefined') module.exports = frac; | ||||
| ``` | ||||
| 
 | ||||
| @ -234,7 +241,7 @@ xltestfiles.forEach(function(x) { | ||||
| ```json>package.json | ||||
| { | ||||
|   "name": "frac", | ||||
|   "version": "1.0.0", | ||||
|   "version": "1.0.1", | ||||
|   "author": "SheetJS", | ||||
|   "description": "Rational approximation with bounded denominator", | ||||
|   "keywords": [ "math", "fraction", "rational", "approximation" ], | ||||
| @ -267,6 +274,17 @@ test_files/*.tsv | ||||
| .gitignore | ||||
| node_modules/ | ||||
| coverage.html | ||||
| .travis.yml | ||||
| .jshintrc | ||||
| .jscs.json | ||||
| .flowconfig | ||||
| misc/ | ||||
| *.sheetjs | ||||
| *.pyc | ||||
| build/ | ||||
| MANIFEST | ||||
| *.gz | ||||
| *.tgz | ||||
| ``` | ||||
| 
 | ||||
| Don't include the node modules in git: | ||||
| @ -275,4 +293,10 @@ Don't include the node modules in git: | ||||
| .gitignore | ||||
| node_modules/ | ||||
| coverage.html | ||||
| *.sheetjs | ||||
| *.pyc | ||||
| build/ | ||||
| MANIFEST | ||||
| *.gz | ||||
| *.tgz | ||||
| ``` | ||||
|  | ||||
							
								
								
									
										73
									
								
								frac.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										73
									
								
								frac.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,73 @@ | ||||
| # frac.py (C) 2015 SheetJS -- http://sheetjs.com | ||||
| # vim: set fileencoding=utf-8 : | ||||
| """ | ||||
| Rational approximations to numbers | ||||
| 
 | ||||
| This module can generate fraction representations using: | ||||
| - Mediant method (akin to fractions.Fraction#limit_denominator) | ||||
| - Aberth method (as used by spreadsheet software) | ||||
| 
 | ||||
| All functions take 3 arguments: | ||||
| 
 | ||||
| - x: the number to be approximated | ||||
| - D: the max denominator | ||||
| - mixed: if True, generate a mixed representation | ||||
| 
 | ||||
| The return value is a list of 3 elements: [quotient, numerator, denominator] | ||||
| """ | ||||
| 
 | ||||
| import math as Math | ||||
| 
 | ||||
| 
 | ||||
| def med(x, D, mixed=False): | ||||
|     """Generate fraction representation using Mediant method""" | ||||
|     n1, d1 = int(Math.floor(x)), 1 | ||||
|     n2, d2 = n1+1, 1 | ||||
|     m = 0. | ||||
|     if x != n1: | ||||
|         while d1 <= D and d2 <= D: | ||||
|             m = float(n1 + n2) / (d1 + d2) | ||||
|             if(x == m): | ||||
|                 if d1 + d2 <= D: | ||||
|                     n1, d1 = n1 + n2, d1 + d2 | ||||
|                     d2 = D + 1 | ||||
|                 elif d1 > d2: | ||||
|                     d2 = D+1 | ||||
|                 else: | ||||
|                     d1 = D+1 | ||||
|                 break | ||||
|             elif x < m: | ||||
|                 n2, d2 = n1+n2, d1+d2 | ||||
|             else: | ||||
|                 n1, d1 = n1+n2, d1+d2 | ||||
|     if d1 > D: | ||||
|         n1, d1 = n2, d2 | ||||
|     if not mixed: | ||||
|         return [0, n1, d1] | ||||
|     q = divmod(n1, d1) | ||||
|     return [q[0], q[1], d1] | ||||
| 
 | ||||
| 
 | ||||
| def cont(x, D, mixed=False): | ||||
|     """Generate fraction representation using Aberth method""" | ||||
|     sgn = -1 if x < 0 else 1 | ||||
|     B = abs(x) | ||||
|     P_2, P_1, P = 0, 1, 0 | ||||
|     Q_2, Q_1, Q = 1, 0, 0 | ||||
|     while Q_1 < D: | ||||
|         A = int(Math.floor(B)) | ||||
|         P = A * P_1 + P_2 | ||||
|         Q = A * Q_1 + Q_2 | ||||
|         if ((B - A) < 0.0000000005): | ||||
|             break | ||||
|         B = 1. / (B-A) | ||||
|         P_2, P_1 = P_1, P | ||||
|         Q_2, Q_1 = Q_1, Q | ||||
|     if(Q > D): | ||||
|         P, Q = P_1, Q_1 | ||||
|     if(Q > D): | ||||
|         P, Q = P_2, Q_2 | ||||
|     if not mixed: | ||||
|         return [0, sgn * P, Q] | ||||
|     q = divmod(sgn * P, Q) | ||||
|     return [q[0], q[1], Q] | ||||
							
								
								
									
										79
									
								
								index.html
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										79
									
								
								index.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,79 @@ | ||||
| <!DOCTYPE html> | ||||
| <!-- frac.js (C) 2015 SheetJS http://sheetjs.com --> | ||||
| <!-- vim: set ts=2: --> | ||||
| <html> | ||||
|   <head> | ||||
|     <title>Fraction Live Demo</title> | ||||
|     <script src="frac.js"></script> | ||||
|   </head> | ||||
|   <body> | ||||
|     <b>Fraction Live Demo</b><br /> | ||||
|     <a href="https://github.com/SheetJS/frac">Source Code</a><br /> | ||||
|     <a href="https://github.com/SheetJS/frac/issues">Issues?  Something look weird?  Click here and report an issue</a><br /> | ||||
|     <br /> | ||||
|     <table> | ||||
|       <tr><td><b>Number:</b></td><td><input type="text" id="val" value="1.3"></td></tr> | ||||
|       <tr><td><b>Denominator Digits:</b></td><td><input type="text" id="fmt" value="1"></td></tr> | ||||
|       <tr><td><b>Use Mixed Fraction:</b></td><td><input type="checkbox" id="mix" name="mixd" checked></td></tr> | ||||
|       <tr><td colspan="2"> </td></tr> | ||||
|       <tr><td><b>Mediant Fraction:</b></td><td><pre id="frm"></pre></td></tr> | ||||
|       <tr><td><b>Aberth Fraction:</b></td><td><pre id="fra"></pre></td></tr> | ||||
|     </table> | ||||
|   </body> | ||||
|   <script> | ||||
|     var V = document.getElementById('val'); | ||||
|     var F = document.getElementById('fmt'); | ||||
|     var X = document.getElementById('mix'); | ||||
|     var M = document.getElementById('frm'); | ||||
|     var A = document.getElementById('fra'); | ||||
| 
 | ||||
|     function update() { | ||||
|       var x, D, mixed, oM, oA; | ||||
|       x = Number(V.value); | ||||
|       D = Math.pow(10, Number(F.value))-1; | ||||
|       mixed = X.checked; | ||||
|       if(x !== x) { M.innerHTML=A.innerHTML = V.value + " not valid"; return; } | ||||
|       if(D !== D) { M.innerHTML=A.innerHTML = F.value + " not valid"; return; } | ||||
|       try { | ||||
|         oM = frac(x, D, mixed); | ||||
|         M.innerHTML = oM[0] + " " + oM[1] + "/" + oM[2]; | ||||
|       } catch(e) { M.innerHTML = e.message; } | ||||
|       try { | ||||
|         oA = frac.cont(x, D, mixed); | ||||
|         A.innerHTML = oA[0] + " " + oA[1] + "/" + oA[2]; | ||||
|       } catch(e) { A.innerHTML = e.message; } | ||||
|     } | ||||
| 
 | ||||
|     /* Bind to relevant events */ | ||||
|     if(F.addEventListener) { | ||||
|       F.addEventListener('keyup', update); | ||||
|       V.addEventListener('keyup', update); | ||||
|       M.addEventListener('change', update); | ||||
|       X.addEventListener('change', update); | ||||
|     } else if(F.attachEvent) { | ||||
|       F.attachEvent('onkeyup', update); | ||||
|       V.attachEvent('onkeyup', update); | ||||
|       M.attachEvent('onchange', update); | ||||
|       X.attachEvent('onchange', update); | ||||
|     } else { | ||||
|       F.oninput = update; | ||||
|       V.oninput = update; | ||||
|       M.onchange = update; | ||||
|       X.onchange = update; | ||||
|     } | ||||
| 
 | ||||
|     update(); | ||||
|   </script> | ||||
|   <script type="text/javascript"> | ||||
|     var _gaq = _gaq || []; | ||||
|     _gaq.push(['_setAccount', 'UA-36810333-1']); | ||||
|     _gaq.push(['_trackPageview']); | ||||
| 
 | ||||
|     (function() { | ||||
|       var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; | ||||
|       ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; | ||||
|       var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); | ||||
|     })(); | ||||
|   </script> | ||||
| </html> | ||||
| 
 | ||||
							
								
								
									
										14
									
								
								misc/spin.sh
									
									
									
									
									
										Executable file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										14
									
								
								misc/spin.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,14 @@ | ||||
| #!/bin/bash | ||||
| # spin.sh -- show a spinner (for coverage test) | ||||
| # Copyright (C) 2014-2015  SheetJS | ||||
| 
 | ||||
| wpid=$1 | ||||
| delay=1 | ||||
| str="|/-\\" | ||||
| while [ $(ps -a|awk '$1=='$wpid' {print $1}') ]; do | ||||
|   t=${str#?} | ||||
|   printf " [%c]" "$str" | ||||
|   str=$t${str%"$t"} | ||||
|   sleep $delay | ||||
|   printf "\b\b\b\b" | ||||
| done | ||||
							
								
								
									
										11
									
								
								misc/strip_sourcemap.sh
									
									
									
									
									
										Executable file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										11
									
								
								misc/strip_sourcemap.sh
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,11 @@ | ||||
| #!/bin/bash | ||||
| # strip_sourcemap.sh -- strip sourcemaps from a JS file (missing from uglifyjs) | ||||
| # Copyright (C) 2014-2015  SheetJS | ||||
| 
 | ||||
| if [ $# -gt 0 ]; then | ||||
| 	if [ -e "$1" ]; then | ||||
| 		sed -i .sheetjs '/sourceMappingURL/d' "$1" | ||||
| 	fi | ||||
| else | ||||
| 	cat - | sed '/sourceMappingURL/d' | ||||
| fi | ||||
| @ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "frac", | ||||
|   "version": "1.0.0", | ||||
|   "version": "1.0.1", | ||||
|   "author": "SheetJS", | ||||
|   "description": "Rational approximation with bounded denominator", | ||||
|   "keywords": [ "math", "fraction", "rational", "approximation" ], | ||||
|  | ||||
							
								
								
									
										28
									
								
								setup.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										28
									
								
								setup.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | ||||
| from distutils.core import setup | ||||
| setup( | ||||
| 	name='frac', | ||||
| 	version='0.0.1', | ||||
| 	author='SheetJS', | ||||
| 	author_email='dev@sheetjs.com', | ||||
| 	url='http://oss.sheetjs.com/frac', | ||||
| 	description='Rational approximations to numbers', | ||||
| 	long_description = """ | ||||
| Rational approximations to numbers | ||||
| 
 | ||||
| This module can generate fraction representations using: | ||||
| - Mediant method (akin to fractions.Fraction#limit_denominator) | ||||
| - Aberth method (as used by spreadsheet software) | ||||
| """, | ||||
| 	platforms = ["any"], | ||||
| 	requires=[], | ||||
| 	py_modules=['frac'], | ||||
| 	scripts = [], | ||||
| 	license = "Apache-2.0", | ||||
| 	keywords = ['frac', 'fraction', 'rational', 'approximation'], | ||||
| 	classifiers = [ | ||||
| 		'Development Status :: 3 - Alpha', | ||||
| 		'License :: OSI Approved :: Apache Software License', | ||||
| 		'Topic :: Office/Business', | ||||
| 		'Topic :: Utilities', | ||||
| 	] | ||||
| ) | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user