I have to do some bitwise operations to perform collision checking for my game, but, I've stumbled into some hexadecimal notation I don't know.
Example from: http://www.yoyogames.com/tech_blog/7
Using the binary tricks above, we can do a simple AND with Y coordinate
Y = Y & $fffffff0
, and this will rid us of the lower bits making the value a multiple of 16, and placing it outside the collision, and back to 64; since
%1001000 (68) & $fffffff0 = %1000000 (64).
Another formula, from: http://gmc.yoyogames.com/index.php?showtopic=552034
$fffffff0 = 4294967280 = ~$F = ~15
$ffffffe0 = 4294967264 = ~$1F = ~31
What kind of hexadecimal notation is this? What does the '$' mean?
~ is the operator for bitwise operation NOT. What it does is invert all bits. 0 become 1 and 1 become 0.
$ preceeding the value tells the compiler its an hexadecimal number. Without it, fffffff0 would be understood as being a variable name.
So you see while 15 means 15 decimal and f hexadecimal, $15 is 15 hexadecimal and 21 decimal.
Related
I ma using MT4 but it might be the general question of floating number.
I am using NormalizeDouble function which rounds the digit of numbers like this.
double x = 1.33242
y = NormalizeDouble(x,2) // y is 1.33
However in some case.
Even after rounded by NormalizeDouble, there happens a number such us 0.800000001
I have no idea why it happens and how to fix it.
It might be a basic mathematical thing.
You are truncating to powers of 10 but fractional part of float/double can express exactly only powers of 2 like
0.5,0.25,0.125,...
and numbers decomposable to them hence your case:
0.8 = 1/2+1/4 +1/32 +1/64 +1/512 +1/1024 +1/8192 +1/16384...
= 0.5+0.25+0.03125+0.015625+0.001953125+0.0009765625+0.0001220703125+0.00006103515625...
= 0.11001100110011... [bin]
as 0.3 is like periodic number in binary and will always cause some noise in lower bits of mantissa. The FPU implementation tries to find the closest number to your desired value hence the 0.800000001
How to represent 500.2 in binary number system. I want to know the conversion method. I know how to convert numbers without points but if point comes in any number I don't know how to convert it.
Quoting the conversion description from Modern Digital Electronics 4E
Decimal to Binary conversion :
Any decimal number can be converted into its equivalent binary number.
For integers, the conversion is obtained by continuous division by 2
and keeping track of the remainders, while for fractional parts, the
conversion is affected by continuous multiplication by 2 and keeping
track of the integers generated.
The conversion process in your case is illustrated below :-
500/2 = 250 Remainder = 0
250/2 = 125 Reaminder = 0
125/2 = 62 Remainder = 1
62/2 = 31 Remainder = 0
31/2 = 15 Remainder = 1
15/2 = 7 Remainder = 1
7/2 = 3 Remainder = 1
3/2 = 1 Remainder = 1
1/2 = 0 Remainder = 1
So, the order of evaluation is that topmost remainder will go to LSB, the bottom-most remainder would go to MSB.
Therefore, (500)2 = 111110100.
Now, talking about the fractional part, we would go as follows :-
// separate the integer generated(0 or 1) on the left hand side of the fraction/dot,
// and ensure only fractional part between 0 and 1 are allowed in the next step
0.2 * 2 = 0.4 , so, keep 0 in the bag
0.4 * 2 = 0.8 , so, keep 0 in the bag
0.8 * 2 = 1.6 , so, keep 1 in the bag, and next put 0.6 to the next step
0.6 * 2 = 1.2, so, keep 1 in the bag, and next put 0.2 to the next step
0.2 * 2 = 0.4, so, keep 0 in the bag...
// and so on as we see that it would continue(repeating) the same pattern.
As we find that the series would go on infinitely, we can consider only the precision upto certain decimal places.
So, if I assume that the required precision is 4 digits after the dot, then the answer would be the sequence in which the digits are being placed in the bag, i.e.,
(0.2)2 = 0.00110011...
= 0.0011....
= 0.0011.
Now, combinedly, (500.2)2 = 111110100.0011 .
Here is a good webpage about it. I don't know if it answers your question :
http://www.h-schmidt.net/FloatConverter/IEEE754.html
Edit
from that link
Usage: You can either convert a number by choosing its binary representation in the button-bar, the other fields will be updated immediately. Or you can enter a binary number, a hexnumber or the decimal representation into the corresponding textfield and press return to update the other fields. To make it easier to spot eventual rounding errors, the selected float number is displayed after conversion to double precision.
Special Values: You can enter the words "Infinity", "-Infinity" or "NaN" to get the corresponding special values for IEEE-754. Please note there are two kinds of zero: +0 and -0.
Conversion: The value of a IEEE-754 number is computed as:
sign * 2exponent * mantissa
The sign is stored in bit 32. The exponent can be computed from bits 24-31 by subtracting 127. The mantissa (also known as significand or fraction) is stored in bits 1-23. An invisible leading bit (i.e. it is not actually stored) with value 1.0 is placed in front, then bit 23 has a value of 1/2, bit 22 has value 1/4 etc. As a result, the mantissa has a value between 1.0 and 2. If the exponent reaches -127 (binary 00000000), the leading 1 is no longer used to enable gradual underflow.
Underflow: If the exponent has minimum value (all zero), special rules for denormalized values are followed. The exponent value is set to 2-126 while the "invisible" leading bit for the mantissa is no longer used. The range of the mantissa is now [0:1).
Note: The converter used to show denormalized exponents as 2-127 and a denormalized mantissa range [0:2). This is effectively identical to the values above, with a factor of two shifted between exponent and mantissa. However this confused people and was therefore changed (2015-09-26).
Rounding errors: Not every decimal number can be expressed exactly as a floating point number. This can be seen when entering "0.1" and examining its binary representation which is either slightly smaller or larger, depending on the last bit.
Other representations: The hex representation is just the integer value of the bitstring printed as hex. Don't confuse this with true hexadecimal floating point values in the style of 0xab.12ef.
I was looking at some code today for integrating a real time clock with an arduino and it had some binary to decimal (and vice versa) that I don't fully understand.
The code in question is below:
byte decToBcd(byte val)
{
return ( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val)
{
return ( (val/16*10) + (val%16) );
}
ex: decToBcd(12);
I really fail to grasp how this works. I am not sure I understand the math, or if some sort of assumptions are being taken advantage of.
Would someone mind explaining how exactly the math and data types below are supposed to work? If possible touching on why the value "16" is used in the conversions instead of "8" when we are supposed to be working with a byte value.
For context, the full code can be found here: http://www.codingcolor.com/microcontrollers/an-arduino-lcd-clock-using-a-chronodot-rtc/
The key hint here is BCD - Binary-coded decimal - in the function name. In BCD each decimal digit is represented by four bits (half of a byte). As a result the maximum (decimal) number you can store using BCD notation is 99 - 9 in the upper nibble (half of the byte) and 9 in the lower nibble.
Let's take a look at number 12 as an example. Number 12 looks as follows in the binary notation:
12 = %00001010
However in BCD it looks as follows:
12 = %00010010
because
0001 0010
1 2
Now if you look at the decToBcd function val%10 is responsible for calculating the value of the ones place (i.e. the last digit). Since this goes to the lower part of the byte we don't need to do anything special here. val/10*16 first calculates the value of the tens place - val/10. However since the value has to go to the upper half of the byte it needs to be shifted up by four bits - hence *16. Another (in my opinion more readable) way of writing this function would be:
((val / 10) << 4) | (val % 10)
The bcdToDec does the reverse conversion.
RTC usually stores Year in 1 byte as 2 digits only, i.e: 2014 is 14.
And some of them stores it as a number from the year 1970 so 2014 = 44.
So maximum it can hold is 99 in both cases.
i've been asked to work on the following question with the following specification/ rules...
Numbers are held in 16 bits split from left to right as follows:
1 bit sign flag that should be set for negative numbers and otherwise clear.
7 bit exponent held in Excess 63
8 bit significand, normalised to 1.x with only the fractional part stored – as in IEEE 754
Giving your answers in hexadecimal, how would the number -18 be represented in this system?
the answer is got is: 11000011 00100000 (or C320 in hexadecimal)
using the following method:
-18 decimal is a negative number so we have the sign bit set to 1.
18 in binary would be 0010010. This we could note down as 10010. We know work on what’s on the right side of the decimal point but in this case we don’t have any decimal point or fractions so we note down 0000 0000 since there are no fractions. We now write down the binary of 18 and the remainder zeroes (which are not necessarily required) and separate them with a decimal point as shown below:
10010.00000000
We now normalise this into the form 1.x by moving the decimal point and placing it between the first and second number (counting the amount of times we move the decimal point until it reaches that area). The result now is 1.001000000000 x 2^4 and we also know that the decimal point has been moved 4 times which for now we will consider to be our exponent value. The floating point system we are using has 7 bit exponent and uses excess 63. The exponent is 4 in excess 63 which would equal to 63 + 4 = 67 and this in 7 bit binary is shown as 1000011.
The sign bit is: 1 (-ve)
Exponent is: 1000011
Significand is 00100…
The binary representation is: 11000011 00100000 (or C320 in hexadecimal)
please let me know if it's correct or if i've done it wrong and what changes could be applied. thank you guy :)
Since you seem to have been assigned a lot of questions of this type, it may be useful to write an automated answer checker to validate your work. I've put together a quick converter in Python:
def convert_from_system(x):
#retrieve the first eight bits, and add a ninth bit to the left. This bit is the 1 in "1.x".
significand = (x & 0b11111111) | 0b100000000
#retrieve the next seven bits
exponent = (x >> 8) & 0b1111111
#retrieve the final bit, and determine the sign
sign = -1 if x >> 15 else 1
#add the excess exponent
exponent = exponent - 63
#multiply the significand by 2^8 to turn it from 1.xxxxxxxx into 1xxxxxxxx, then divide by 2^exponent to get back the decimal value.
result = sign * (significand / float(2**(8-exponent)))
return result
for value in [0x4268, 0xC320]:
print "The decimal value of {} is {}".format(hex(value), convert_from_system(value))
Result:
The decimal value of 0x4268 is 11.25
The decimal value of 0xc320 is -18.0
This confirms that -18 does convert into 0xC320.
I may formulated the question a bit wrong. I need to calculate the IPv4 header checksum in hexadecimal with paper and pen. At this link http://en.wikipedia.org/wiki/IPv4_header_checksum
on the last example they do it.
I have a bit of problem understanding how they count directly in hexadecimal. When doing it on paper what if I get a number over 15 for example 48 what reminder will I use and what will I write down?
Anyone that can explain how to handle this?
Thank you and sorry for formulating the question wrong but I have changed it now:)
See http://www.youtube.com/watch?v=UGK8VyV1gLE which describes the process very well.
Counting in HEX (base 16) is just like counting in decimal (base 10) except that you only start carrying remainders when you count past F.
So in your example from a comment, it's just like counting in decimal with no remainders:
15
24
---
39
A simple true HEX addition is:
11
F
---
20
1 + F = 10 = 1 remainder + 1 = 20
15 over 48 is simple too:
15
48
---
5D
8 + 5 = D no remainder, 1 + 4 = 5 no remainder
Hexadecimal is just a representation of numbers. In order to have the computer helping you with the addition you will have to convert the hexadecimal represented numbers to a number itself then do the addition and then convert it back. This is not a conversion to binary as binary is also only a different representation.
If you do not want the conversion from hexadecimal you will have to explain why you do not want to have this conversion.
I suppose this may sound like a dumb answer, but it's the best I can give with the way you wrote the question.
Addition in hex works exactly the same as in decimal, except with 16 instead of 10 digits. So in effect, what you're asking is how to do addition in general (including in decimal.) In dec, 9 + 1 = 10. In hex, F + 1 = 10. Obviously, the same rules of addition apply in both.