It's not just E24 values I'm doing it for the E192 values too. In the end I want to make it so you can choose between E3, E6, E12, E24, E48, E96 and E192 values.
There's nothing weird about that formula, it's just a standard geometric sequence, i is the index and b is the base. For example to calculate the 21th E48 value R = 10^(21/48) = 2.74.
To get the index from the value, transpose the formula. i = 48*log10(2.74) = 21.
If the value is not an exact E value then all we need to do is round the result to the nearest integer and it gives the index of nearest E value.
i = 48*log10(2.7) = 20.7 = 21.
I am using look up tables. The formula creates all the values and the above transposition of the formula indexes the tables. I could have used a search to find the value but that would probably have proven slow on the E192 values.
First the arrays are filled with E24 and E192 values and which are fiddled so they equal the standard EA values.
The program requests the desired value from the user.
The transposition of the origional formula is used to index the array to get the nearest value.
This is compared with the mantissa, if it's too big the next smallest value is used, if it's too bit the next largest value is used.
I'm using old QBasic because it's the only language I know. You can still download it from the MS website and there's an open-source clone FreeBasic which is 95% QB compatible.
Here's the program:
Code:
DEFINT A-Z ' Set default variable type to integer.
DIM SHARED values(1 TO 216)' An array for the E24 values and E192 values.
DIM SHARED lgb10 AS DOUBLE ' Define log10 so we don't have to recalculate it.
lgb10 = LOG(10)
CLS
FOR n = 1 TO 24 ' Calculate the E24 values.
values(n) = 10 ^ (1 + n / 24)
IF n >= 10 AND n <= 16 THEN values(n) = values(n) + 1 'Fiddle to fit E24
values(n) = values(n) * 10
NEXT
values(22) = 820' Fiddle to fit E24
FOR n = 1 TO 192
values(n + 24) = 10 ^ (2 + n / 192)
NEXT
values(209) = 920' Fiddle to fit E192
FOR n = 1 TO 24
PRINT values(n)
NEXT
INPUT "Enter value"; value#
lgval# = LOG(value#) / lgb10' Take log10 of the value.
ex = INT(lgval#)' Exponent is the integer part of log 10 of the value.
dec#= lgval# - ex' store the decimal part of log10.
el = dec#* 24' Work out the nearest preferred number.
mnt = 10 ^ (2 + dec#)' get the mantissa.
ex = ex - 2' Preferred numbers in the array are multiplied by 100 so /100.
IF el = 0 THEN ' If zero, wrap round to highest value and /10 to compensate.
ex = ex - 1
el = 24
mnt = mnt * 10
END IF
' A fiddle to align the result to the preferred number.
dif = values(el) - mnt' The difference between the ideal and preferred value.
IF el > 1 THEN IF dif > mnt - values(el - 1) THEN el = el - 1
IF el < 24 THEN IF dif < mnt - values(el + 1) THEN el = el + 1
PRINT "Index"; el
PRINT "Mantissa"; mnt
PRINT "Exponent:"; ex
PRINT "Nearest E24 Value"; values(el) * 10 ^ ex
Just for referance, here's a program which finds the nearest E96 value. E96 values are just a standard geometric sequance so no silly tweaking or look-up tables are required. Look at how much simpler the program is. I could have done it all in one line if I'd wanted to.
Code:
DIM lg10 AS DOUBLE
DEFINT A-Z
lg10 = LOG(10)
INPUT "Enter value"; r#
lg10r# = LOG(r#) / lg10
ex = INT(lg10r#)
PRINT ex
E96 = CINT(10 ^ (2 + CINT(96 * LOG(10 ^ (lg10r# - ex)) / lg10) / 96)) * 10 ^ (ex - 2)
PRINT E96
For those who don't know QBasic.
CINT rounds the number to an integer, i.e CINT(9.6) = 10 and INT converts the number an integer simply by removing all the decimal places, i.e INT(9.6) = 9.
When a interger variable is set to a floating point value, it's just rounded to the nearest integer.
LOG is the natural logarithm, there's no way to to Log to the base x in QB, you have to do LOG(n)/LOG(b).