/** Generates numbers in a range from min to max with a logarithmic scale, that is, each magnitude is equally probable. For example: randomLog[1e-10, 1e+10] will generate numbers across the specified range. The min and max must have the same sign. TODO: Add a clamp to make sure the rounded digits are in the specified range after rounding? TODO: Have a "fast" version that doesn't round to specified number of digits? TODO: Does this work right with 1 digit? Test bounds of [1e-10, 1e10, 1] which gives some 1e+20 results?! */ randomLog[min, max] := { range = max/min if realSignum[range] <= 0 { println["randomLog: passed invalid range $min - $max."] return undef } return min 10^(randomFloat[0, log[range]]) } /** This is the same as randomLog[min, max] above but rounds to the specified number of significant (decimal) digits. This calls setPrecision so it cannot currently be used in a secure context. */ randomLog[min, max, digits] := { val = randomLog[min, max] if val == undef return val origPrec = getPrecision[] try { setPrecision[digits] return 1. val } finally setPrecision[origPrec] }