how can i get numbers like 0.001 or 0.5 in binary

Thread Starter

Just me1

Joined Sep 3, 2017
59
hi reader!

i have been working on a 16 bit alu for a little while, and finally made a multiplier and divider that work properly, but then i was thinking it should be able to use numbers like 0.001, 0.5 and 3.14 would be nice too, but how can i get that.

and if you know how to do this below please help
i want the functions cos sin and tan, and cos-1 sin-1, tan-1, but again have no idea how to do that
 
Although, you can extend the weights past the decimal point.

e.g.
2^-1 = 0.5
2^-2 = 0.25
2^-3 = 0.125
and so on.

so 101.001 is 5.125

Floating point is usually encoded as:

https://www.h-schmidt.net/FloatConverter/IEEE754.html

Just like there is an ALU (Arithmetic Logic Unit), there was an FPU (Floating Point Unit)

There was a 4 bit TTL chip that did Arithmetic and Logic. Also look at the AMD2900 series chips (Obsolete).

Old PDP-11 documentation should have some Floating Point instructions in it. It won't likely be the IEEE format though,

This http://www.quadibloc.com/comp/cp0201.htm might be useful.

here https://en.wikipedia.org/wiki/PDP-11_architecture is some info about the PDP-11 architecture.

And for a really detailed PDP-11 FPU description: ftp://bitsavers.informatik.uni-stuttgart.de/pdf/dec/pdp11/1144/EK-FP11F-TM-002_Nov79.pdf

Here http://www.acsel-lab.com/arithmetic/arith14/papers/ARITH14_Story.pdf is some info on Trancendental functions.

and here:
http://www.qc.cuny.edu/Academics/Degrees/DMNS/Faculty Documents/Sultan1.pdf
 
Last edited:

joeyd999

Joined Jun 6, 2011
6,242
To avoid the complexity of floating point notation, you can use fixed point notation. You just define an imaginary "binary point" at some location in your binary word.

For instance, you can imagine a binary point between two 8 bit bytes of a 16 bit integer:

10001100 . 11001010

The value to the left of the binary point is just the 8 bit whole number 0 through 255. The right portion is the fraction, and has a value of x/256, where x is -- again -- a whole number.

All basic mathematical operations are valid upon the fixed point number -- addition, subtraction, multiplication, and division.

When multiplying and dividing, you must remember that the fixed point position shifts (just like with decimal numbers). For instance:

aaaaaaa.bbbbbbbb * cccccccc.dddddddd = ffffffff gggggggg . hhhhhhhh iiiiiiiiii

Notice that the decimal shifted one full byte to the left in the result.
 

WBahn

Joined Mar 31, 2012
32,746
The simpler option for a home-rolled ALU is probably fixed-point. But with only 16 bits to work with you quickly run out of range on both the large and small ends of the scale. You also have to be careful to track the scaling properly as you multiply and divide and also be sure that you are dealing with negative number representations properly.

There actually is an IEE-754 spec for a 16-bit floating point representation (the half-precision standard), but it is meant primarily for data storage and not actual manipulation since it is so limited. Implementing a floating point processor is not a trivial undertaking -- there's a reason that for years PC's had no native floating point support unless you bought an expensive floating point coprocessor.

The most practical solution is to do it the same way that those old PCs did -- emulate non-integer math in software. That also allows you to use your 16-bit integer ALU to do 64-bit floating point math if you want to.
 

BobTPH

Joined Jun 5, 2013
11,480
Sometimes it is convenient to just use scaled values.

For example, if you interested in measuring voltage between -10 and 10V and you need an accuracy of 10mV, you simply represent the voltage in units of 10mV. In other words,

1 = 10mV
2 = 20mV
10 = 100mV
100 = 1V
1000 = 10V
-1000 = -10V

This is similar to fixed point, but less efficient since you will have to multiply and divide by powers of 10 instead of powers of 2, which is more efficient. But I think it is easier to get your head around as a beginner.

Adding and subtracting work like normal, just as in fixed point. For multiply and divide you will need to represent the intermediate results as 32-bit. For instance, if multiplying two of your 10mV numbers, you will have to divide by 100 after the multiplcation, since each number is multiplied by 100 and the result of the multiplication would be multiplied by 10,000. On divide it works the other way, multiply by 100 as a 32-bit number before dividing.

Bob
 

Thread Starter

Just me1

Joined Sep 3, 2017
59
well.. i think i would just keep it at what my first thoughts were

100 x 0.5 could also be written as 1000 x 5 divided by 10
it needs a few more steps to do this stuff, but my computer isnt going to be focussed on speed, so the time loss of maybe 0.001 milisecond isnt that bad
 

Thread Starter

Just me1

Joined Sep 3, 2017
59
i do have to change some things at the inputs, becouse it would need some bits to indicate how small the number is, but im not sure if it would be able to use and create numbers like 3.14, so that's why im thinking of inputs with 27 bits, 16 for whole numbers like 1, 2, 3 etc. and 4 to indicate the greatness of the numbers behind the whole ones, and 7 for the number itsself ( up to 99 )
 
Last edited:

joeyd999

Joined Jun 6, 2011
6,242
Don't get hung up on a particular kind of representation. Take some time to learn them all: integer, fixed point, floating point. And learn each of their strengths and weaknesses, including the range of values they can represent and their ultimate resolution vs. bit length, and how to calculate these things. Also, be aware that more complex types (and longer word sizes) require more CPU instructions to work on them.

The representation you choose to use will have a great impact on the ease of programming later. You choose the representation based upon the kind of data you wish to represent. Mixing types also makes sense where applicable.

As an example, I tend to capture A/D data as a fixed point fraction of appropriate size for the converter in questions. A fixed point fraction is simply a binary number with the binary point to the far left (as opposed to the far right for a simple integer). Its range is 0.0 to 1.0, with a resolution depending on the number of bits.

Suppose my A/D is 10 bits. This requires a 16 bit integer, and I'd align (left justify) the A/D result to the left so that the bit 9 shifts to the bit 15 position. Or, I could oversample, and add 64 right justified conversions, resulting in a full 16 bit fractional result -- again with a value of 0.0 to 1.0.

If I want to convert the A/D result to, say mV, and the reference voltage is, say, 2.5V, I simply multiply the fractional result of the A/D by 2,500*, and I've got my answer.

Easy peasy lemon squeezy.

*I usually add 0.5 to the final result for proper rounding if I intend to truncate the final answer to a whole number.
 
Last edited:

Thread Starter

Just me1

Joined Sep 3, 2017
59
Don't get hung up on a particular kind of representation. Take some time to learn them all: integer, fixed point, floating point. And learn each of their strengths and weaknesses, including the range of values they can represent and their ultimate resolution vs. bit length, and how to calculate these things. Also, be aware that more complex types (and longer word sizes) require more CPU instructions to work on them.

The representation you choose to use will have a great impact on the ease of programming later. You choose the representation based upon the kind of data you wish to represent. Mixing types also makes sense where applicable.

As an example, I tend to capture A/D data as a fixed point fraction of appropriate size for the converter in questions. A fixed point fraction is simply a binary number with the binary point to the far left (as opposed to the far right for a simple integer). Its range is 0.0 to 1.0, with a resolution depending on the number of bits.

Suppose my A/D is 10 bits. This requires a 16 bit integer, and I'd align (left justify) the A/D result to the left so that the bit 9 shifts to the bit 15 position. Or, I could oversample, and add 64 right justified conversions, resulting in a full 16 bit fractional result -- again with a value of 0.0 to 1.0.

If I want to convert the A/D result to, say mV, and the reference voltage is, say, 2.5V, I simply multiply the fractional result of the A/D by 2,500*, and I've got my answer.

Easy peasy lemon squeezy.

*I usually add 0.5 to the final result for proper rounding if I intend to truncate the final answer to a whole number.
well.. learning that would have to wait til next week friday, got a lot of tests i still gotta learn for, probably do have some free time then, becouse i only gotta go to school for a test from this friday to next friday
 

MrChips

Joined Oct 2, 2009
34,689
I do all my MCU coding in integer arithmetic. I do temperatures in °C/°F, RH, dewpoint, etc, in integer math.

Tell us what you want to calculate. What is your min and max range of value and what precision you want?
As an example, temperatures can be spec'd at -50°C to +300°C ±0.1°
 

MrChips

Joined Oct 2, 2009
34,689
I can multiply or divide any value with a constant floating point number using integer math.

Need to multiply by pi?
Some people think pi is 22/7. This is very crude approximation.

Check out 355/113.
This is accurate to at least 6 decimal places.
 

Bordodynov

Joined May 20, 2015
3,430
0.5 -->
1) int(0.5)=0
2) int(0.5*2)=1
3) Answer=0.1
0.001
1) int(0.001)=0
2) int(0.002)=0
3) int(0.004)=0
4) int(0.008)=0
5) int(0.016)=0
6) int(0.032)=0
7) int(0.064)=0
8) int(0.128)=0
9) int(0.256)=0
10) int(0.512)=0
11) int(1.024)=1
12) int((1.024-1)*2)=int(0.048)=0
13) int(0.0096)=0
14) int(0.0192)=0
15) int(0.0384)=0
16) int(0.0768)=0
17) int(0.1536)=0
18) int(0.3072)=0
19) int(0.6144)=0
20) int(1.2288)=1
21) int(0.2288*2)=int(0.4576)=0
22) int(0.9152)=0
23) int(1.8304)=1
24) int(0.8304*2)=int(1.6608)=1
25) int(0.6608*2)=int(1.3216)=1
26)int (0.3216*2)=int(0.6432)=0
27) int(0.6432*2)=int(1.2864)=1
28) int(0.5728)=0
29) int(1.1456)=1
......
Answer=0.0000000001000000001001110101......
 

WBahn

Joined Mar 31, 2012
32,746
i have an idea on how to do pi, but how to do cos sin tan?
and the -1 ?
You need to decide what representation you are going to use. Fixed point? Floating point? And then what specific rules you are going to use? IEEE-754? Something you make up? Their are many, many ways to represent numbers, so trying to figure out how to represent a specific number is pointless until you choose the basic representation you are going to use.

If you can represent pi, then you should be able to represent arbitrary non-integer values, at least that are of comparable size.

If you are asking how to compute cosine, sine, and tangent, their a numerous ways to do that, as well. Lookup tables, various series approximations, and the CORDIC algorithms are among the most common. You need to first decide how fast your functions need to be and how accurate they need to be.
 
Top