big steppy
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 

361 lines
13 KiB

  1. 'use strict';
  2. function round(number,precision=3) {
  3. return Math.round(number*Math.pow(10,precision)) / Math.pow(10,precision);
  4. }
  5. function numberRough(value,suffix="") {
  6. if (value == 1) {
  7. return "a single";
  8. } else if (value < 5) {
  9. return "a few";
  10. } else if (value < 12) {
  11. return "a handful " + suffix;
  12. } else if (value == 12) {
  13. return "a dozen";
  14. } else {
  15. var scale = Math.floor(Math.log10(value));
  16. switch(scale) {
  17. case 1: return "dozens " + suffix;
  18. case 2: return "hundreds " + suffix;
  19. default:
  20. let prefix = "";
  21. if (scale % 3 == 1)
  22. prefix = "tens of ";
  23. else if (scale % 3 == 2)
  24. prefix = "hundreds of ";
  25. let order = Math.floor(scale/3);
  26. switch(order) {
  27. case 1: return prefix + "thousands " + suffix;
  28. case 2: return prefix + "millions " + suffix;
  29. case 3: return prefix + "billions " + suffix;
  30. case 4: return prefix + "trillions " + suffix;
  31. case 5: return prefix + "quadrillions " + suffix;
  32. case 6: return prefix + "quintillions " + suffix;
  33. default: return "uncountably many";
  34. }
  35. }
  36. }
  37. }
  38. function number(value, type="full", precision=3) {
  39. var val = parseFloat(value);
  40. switch(type) {
  41. case "full": return val.toString();
  42. case "scientific": return val.toExponential(precision).toString();
  43. case "words": return number_words_repeated(val);
  44. case "prefix": return number_prefix(val);
  45. }
  46. }
  47. function number_words(value) {
  48. var scale = Math.floor(Math.log(value) / Math.log(1000));
  49. if (scale < 0) {
  50. return value.toString();
  51. }
  52. switch(scale) {
  53. case 0: return value.toString();
  54. case 1: return Math.round(value / 1e3).toString() + " thousand";
  55. case 2: return Math.round(value / 1e6).toString() + " million";
  56. case 3: return Math.round(value / 1e9).toString() + " billion";
  57. case 4: return Math.round(value / 1e12).toString() + " trillion";
  58. case 5: return Math.round(value / 1e15).toString() + " quadrillion";
  59. case 6: return Math.round(value / 1e18).toString() + " quintillion";
  60. case 7: return Math.round(value / 1e21).toString() + " sextillion";
  61. case 8: return Math.round(value / 1e24).toString() + " septillion";
  62. case 9: return Math.round(value / 1e27).toString() + " octillion";
  63. case 10: return Math.round(value / 1e30).toString() + " nonillion";
  64. case 11: return Math.round(value / 1e33).toString() + " decillion";
  65. case 12: return Math.round(value / 1e36).toString() + " undecillion";
  66. case 13: return Math.round(value / 1e39).toString() + " duodecillion";
  67. case 14: return Math.round(value / 1e42).toString() + " tredecillion";
  68. case 15: return Math.round(value / 1e45).toString() + " quattuordecillion";
  69. case 16: return Math.round(value / 1e48).toString() + " quindecillion";
  70. case 17: return Math.round(value / 1e51).toString() + " sexdecillion";
  71. case 18: return Math.round(value / 1e54).toString() + " septendecillion";
  72. case 19: return Math.round(value / 1e57).toString() + " octodecillion";
  73. case 20: return Math.round(value / 1e60).toString() + " novemdecillion";
  74. default: return Math.round(value / 1e63).toString() + " vigintillion";
  75. }
  76. }
  77. function number_words_repeated(value) {
  78. if (value == Infinity)
  79. return "a lot of";
  80. var scale = Math.floor(Math.log(value) / Math.log(1000));
  81. if (scale < 0)
  82. return value.toString();
  83. switch(scale) {
  84. case 0: return value.toString();
  85. case 1: return Math.round(value / 1e3).toString() + " thousand";
  86. case 2: return Math.round(value / 1e6).toString() + " million";
  87. case 3: return Math.round(value / 1e9).toString() + " billion";
  88. case 4: return Math.round(value / 1e12).toString() + " trillion";
  89. case 5: return Math.round(value / 1e15).toString() + " quadrillion";
  90. case 6: return Math.round(value / 1e18).toString() + " quintillion";
  91. default: return number_words_repeated(value / 1e18) + " quintillion";
  92. }
  93. }
  94. function number_prefix(value) {
  95. var scale = Math.floor(Math.log(value) / Math.log(1000));
  96. if (scale < 0)
  97. return value.toString();
  98. switch(scale) {
  99. case 0: return value.toString();
  100. case 1: return Math.round(value / 1e3).toString() + "K";
  101. case 2: return Math.round(value / 1e6).toString() + "M";
  102. case 3: return Math.round(value / 1e9).toString() + "G";
  103. case 4: return Math.round(value / 1e12).toString() + "T";
  104. case 5: return Math.round(value / 1e15).toString() + "P";
  105. case 6: return Math.round(value / 1e18).toString() + "E";
  106. case 7: return Math.round(value / 1e21).toString() + "Z";
  107. default: return Math.round(value / 1e24).toString() + "Y";
  108. }
  109. }
  110. function mass(kg, type="metric", singular=false) {
  111. switch(type) {
  112. case "metric": return metricMass(kg, singular);
  113. case "customary": return customaryMass(kg, singular);
  114. case "approx": return approxMass(kg, singular);
  115. }
  116. }
  117. function length(m, type="metric", singular=false) {
  118. switch(type) {
  119. case "metric": return metricLength(m, singular);
  120. case "customary": return customaryLength(m, singular);
  121. case "approx": return approxLength(m, singular);
  122. }
  123. }
  124. function area(m2, type="metric", singular=false) {
  125. switch(type) {
  126. case "metric": return metricArea(m2, singular);
  127. case "customary": return customaryArea(m2, singular);
  128. case "approx": return approxArea(m2, singular);
  129. }
  130. }
  131. function volume(m3, type="metric", singular=false) {
  132. switch(type) {
  133. case "metric": return metricVolume(m3, singular);
  134. case "customary": return customaryVolume(m3, singular);
  135. case "approx": return approxVolume(m3, singular);
  136. }
  137. }
  138. function metricMass(kg, singular=false) {
  139. if (kg < 1/1000) {
  140. let mass = round(kg * 1e6,0);
  141. return mass + (singular || mass == 1 ? " milligram" : " milligrams");
  142. } else if (kg < 1) {
  143. let mass = round(kg * 1000,0);
  144. return mass + (singular || mass == 1 ? " gram" : " grams");
  145. } else if (kg < 5000) {
  146. let mass = round(kg,0);
  147. return mass + (singular || mass == 1 ? " kilogram" : " kilograms");
  148. } else if (kg < 5000000) {
  149. let mass = round(kg / 1000,1);
  150. return mass + (singular || mass == 1 ? " metric ton" : " metric tons");
  151. } else if (kg < 5000000000) {
  152. let mass = round(kg / 1000000,1);
  153. return mass + (singular || mass == 1 ? " kiloton" : " kilotons");
  154. } else if (kg < 5000000000000) {
  155. let mass = round(kg / 1000000000,1);
  156. return mass + (singular || mass == 1 ? " megaton" : " megatons");
  157. } else {
  158. let mass = round(kg / 1000000000000,1);
  159. return mass + (singular || mass == 1 ? " gigaton" : " gigatons");
  160. }
  161. }
  162. function customaryMass(kg, singular=false) {
  163. let lbs = kg * 2.2;
  164. if (lbs < 1) {
  165. let mass = round(lbs * 16,0);
  166. return mass + (singular || mass == 1 ? " ounce" : " ounces");
  167. } else if (lbs < 2000) {
  168. let mass = round(lbs,0);
  169. return mass + (singular || mass == 1 ? " pound" : " pounds");
  170. } else {
  171. let mass = round(lbs / 2000,1);
  172. return mass + (singular || mass == 1 ? " ton" : " tons");
  173. }
  174. }
  175. function approxMass(kg, singular=false) {
  176. if (kg < 10000) {
  177. let mass = round(kg/1000,2);
  178. return (singular || mass == 1 ? "a car" : mass + " cars");
  179. } else if (kg < 100000) {
  180. let mass = round(kg/6000,2);
  181. return (singular || mass == 1 ? "an elephant" : mass + " elephants");
  182. } else if (kg < 1000000000) {
  183. let mass = round(kg/54431.1,2);
  184. return (singular || mass == 1 ? "a tank" : mass + " tanks");
  185. } else if (kg < 1e21) {
  186. let mass = round(kg/1.01605e8,2);
  187. return (singular || mass == 1 ? "an aircraft carrier" : mass + " aircraft carriers");
  188. } else {
  189. let mass = round(kg/5.972e24,4);
  190. return (singular || mass == 1 ? "the Earth" : mass + " Earths");
  191. }
  192. }
  193. function metricLength(m, singular=false) {
  194. if (m < 1/100) {
  195. let length = round(m * 1000,2);
  196. return length + (singular || length == 1 ? " millimeter" : " millimeters");
  197. } else if (m < 1) {
  198. let length = round(m * 100,0);
  199. return length + (singular || length == 1 ? " centimeter" : " centimeters");
  200. } else if (m < 500) {
  201. let length = round(m,2);
  202. return length + (singular || length == 1 ? " meter" : " meters");
  203. } else {
  204. let length = round(m / 1000,1);
  205. return length + (singular || length == 1 ? " kilometer" : " kilometers");
  206. }
  207. }
  208. function customaryLength(m, singular=false) {
  209. let ft = m * 3.28084;
  210. if (ft < 1) {
  211. let length = round(ft * 12,0);
  212. return length + (singular || length == 1 ? " inch" : " inches");
  213. } else if (ft < 5280) {
  214. let end = customaryLength((ft - Math.floor(ft))/3.28084, singular);
  215. let length = Math.floor(ft);
  216. return length + (singular || length == 1 ? " foot" : " feet") + " " + end;
  217. } else {
  218. let length = round(ft/5280,1);
  219. return length + (singular || length == 1 ? " mile" : " miles");
  220. }
  221. }
  222. function approxLength(m, singular=false) {
  223. if (m < 1000) {
  224. let length = round(m/49,1);
  225. return length + (singular || length == 1 ? " football field" : " football fields");
  226. } else if (m < 5000000) {
  227. let length = round(m/449,1);
  228. return length + (singular || length == 1 ? " Empire State Building" : " Empire State Buildings");
  229. } else if (m < 3474574*2) {
  230. let length = round(m/3474574,1);
  231. return length + (singular || length == 1 ? " moon" : " moons");
  232. } else if (m < 12.742e6*100) {
  233. let length = round(m/12.742e6,1);
  234. return length + (singular || length == 1 ? " earth" : " earths");
  235. } else if (m < 149.6e12) {
  236. let length = round(m/149.6e9,1);
  237. return length + (singular || length == 1 ? " AU" : " AUs");
  238. } else if (m < 9.4607e22) {
  239. let length = round(m/9.4607e15,4);
  240. return length + (singular || length == 1 ? " light year" : " light years");
  241. } else if (m < 5e26) {
  242. let length = round(m/9.4607e21,3);
  243. return length + (singular || length == 1 ? " galaxy" : " galaxies");
  244. } else {
  245. let length = round(m/4.40e26,3);
  246. return length + (singular || length == 1 ? " universe" : " universes");
  247. }
  248. }
  249. function metricArea(m2, singular=false) {
  250. if (m2 < 1/10) {
  251. let area = round(m2 * 10000,2);
  252. return area + (singular || area == 1 ? " square centimeter" : " square centimeters");
  253. } else if (m2 < 100000) {
  254. let area = round(m2,2);
  255. return area + (singular || area == 1 ? " square meter" : " square meters");
  256. } else {
  257. let area = round(m2 / 1e6,2);
  258. return area + (singular || area == 1 ? " kilometer" : " square kilometers");
  259. }
  260. }
  261. function customaryArea(m2, singular=false) {
  262. let ft2 = m2 * 3.28084 * 3.28084;
  263. if (ft2 < 1) {
  264. let area = round(ft2 * 144,0);
  265. return area + (singular || area == 1 ? " square inch" : " square inches");
  266. } else if (ft2 < 5280 * 5280 / 10) {
  267. let area = round(ft2,1);
  268. return area + (singular || area == 1 ? " square foot" : " square feet");
  269. } else {
  270. let area = round(ft2 / 5280 / 5280,1);
  271. return area + (singular || area == 1 ? " square mile" : " square miles");
  272. }
  273. }
  274. function metricVolume(m3, singular=false) {
  275. if (m3 < 1/1000) {
  276. let volume = round(m3*1e6, 0);
  277. return volume + (singular || volume == 1 ? " milliliter" : " milliliters");
  278. } else if (m3 < 1) {
  279. let volume = round(m3*1000, 1);
  280. return volume + (singular || volume == 1 ? " liter" : " liters");
  281. } else if (m3 < 1000000) {
  282. let volume = round(m3, 0);
  283. return volume + (singular || volume == 1 ? " cubic meter" : " cubic meters");
  284. } else if (m3 < 1e12){
  285. let volume = round(m3/1e9, 3);
  286. return volume + (singular || volume == 1 ? " cubic kilometer" : " cubic kilometers");
  287. } else {
  288. let volume = round(m3/1e9, 0);
  289. return volume + (singular || volume == 1 ? " cubic kilometer" : " cubic kilometers");
  290. }
  291. }
  292. function customaryVolume(m3, singular=false) {
  293. let gallons = m3 * 264.172;
  294. if (gallons < 1/16) {
  295. let volume = round(gallons*128,0);
  296. return volume + (singular || volume == 1 ? " fluid ounce" : " fluid ounces");
  297. } else if (gallons < 1/4) {
  298. let volume = round(gallons*16,1);
  299. return volume + (singular || volume == 1 ? " cup" : " cups");
  300. } else if (gallons < 1/2) {
  301. let volume = round(gallons*8,1);
  302. return volume + (singular || volume == 1 ? " pint" : " pints");
  303. } else if (gallons < 1) {
  304. let volume = round(gallons*4,1);
  305. return volume + (singular || volume == 1 ? " quart" : " quarts");
  306. } else if (gallons < 100) {
  307. let volume = round(gallons,1);
  308. return volume + (singular || volume == 1 ? " gallon" : " gallons");
  309. } else {
  310. let volume = round(gallons,0);
  311. return volume + (singular || volume == 1 ? " gallon" : " gallons");
  312. }
  313. }
  314. function approxVolume(m3, singular=false) {
  315. if (m3 < 1/10000) {
  316. let volume = round(m3*1e6,0);
  317. return (singular || volume == 1 ? "a shot" : volume + " shots");
  318. } else if (m3 < 1) {
  319. let volume = round(m3*2000,0);
  320. return (singular || volume == 1 ? "a glass" : volume + " glasses");
  321. } else if (m3 < 10) {
  322. let volume = round(m3*2.64,1);
  323. return(singular || volume == 1 ? "a bathtub" : volume + " bathtubs");
  324. } else if (m3 < 1e9) {
  325. let volume = round(m3/1000,2);
  326. return (singular || volume == 1 ? "an Olympic swimming pool" : volume + " Olympic swimming pools");
  327. } else if (m3 < 1e15) {
  328. let volume = round(m3/1.8919e10,3);
  329. return (singular || volume == 1 ? "a Great Salt Lake" : volume + " Great Salt Lakes");
  330. } else {
  331. let volume = round(m3/3.547e17, 3);
  332. return (singular || volume == 1 ? "an ocean" : volume + " oceans");
  333. }
  334. }