Page 1 of 1
>> and <<
Posted: 29 December 2010, 14:38 PM
by sturgessb
Quick question
in the following C code example...
x1 = (ut - ac6) * ac5 >> 15
What would the zxbasic equiv be for the >> 15 ?
Cheers
Ben
Re: >> and <<
Posted: 29 December 2010, 14:47 PM
by dkinzer
sturgessb wrote:What would the zxbasic equiv be for the >> 15 ?
However, if it is a 16-bit value, it may be more efficient to write it as
Code: Select all
IIF(CBool(val And &H8000), 1, 0)
Posted: 29 December 2010, 14:52 PM
by dkinzer
Or, considering the entire expression:
Code: Select all
If CBool(ac5 And &H8000) Then
x1 = (ut - ac6)
Else
x1 = 0
End If
If ac5 is a 32-bit value, using Shr() would be preferred.
Posted: 29 December 2010, 15:16 PM
by sturgessb
Thanks, so the following...
Code: Select all
x1 = (ut - ac6) * ac5 >> 15;
x2 = (mc << 11) / (x1 + md);
b5 = x1 + x2;
temperature = (b5 + 8) >> 4;
Would become....
Code: Select all
X1 = (UT - Clng(ac6)) * Clng(Shr(ac5,15))
X2 = Clng(Shl(mc,11)) \ (X1 + Clng(md))
B5 = X1 + X2
T = Shr((B5 + 8), 4)
Its just im not getting the result i was expecting. Trying to get the following to work
http://www.sparkfun.com/products/9694
Posted: 29 December 2010, 15:51 PM
by dkinzer
In C, multiplication has a
higher precedence than do the shift operators. I think the correct translation of the x1 and x2 expressions is:
Code: Select all
x1 = Shr((ut - CLng(ac6)) * CLng(ac5), 15)
x2 = Shl(CLng(mc), 11) \ (x1 + CLng(md))
Posted: 29 December 2010, 16:33 PM
by mikep
Be careful here. Some C programmers use the left and right shift operators as a way of multiplying or dividing by a power of 2. As a consequence this unneeded optimization disguises the original intent of the code. Unneeded be cause modern compilers including ZBasic will do this out for you.
I did some Googling that first led me to an append on the
Arduino forum and then to the
Bosch BMP085 datasheet. On page 13 of the datasheet it shows the same math using multiplication and division by powers of 2.
Posted: 29 December 2010, 16:51 PM
by sturgessb
hmmm i see
So what does that mean in this example, what would the code be?
Cheers
Ben
Posted: 29 December 2010, 18:07 PM
by mikep
Again all I mean is understand what you are calculating. For example if you are ok working in units of 1/160 of a degree C (such as simple comparisons) then you can eliminate the last part of the calculation.
Code: Select all
T = Shr((B5 + 8), 4)
T is still in units of 0.1 of a degree so you have to do this in any case.
Also the values ac5, ac6, mc and md are calibration values that never change for a given chip. This fact allows us to only do part of the calculation once and simplify the rest (which is therefore faster). In this case there is not much value add but again the point is to understand the original algorithm. I have to say that the Bosch sensor calculation is a little convoluted and they could have put much more of it into the chip itself (see the SCP1000 device).
Code: Select all
' calibration values from device
Dim ac5 as Integer, ac6 as Integer, mc as Integer, md as Integer
' derived values from calibration values
Dim ac6_5prime as Long, mcprime as Long
' uncalibrated temp and calibrated temp
Dim ut as long, t as Long
Sub Main()
' temporary values
Dim x1 as Long, x2 as Long
' calculate once from calibration values
ac6_5prime = Shr(CLng(ac6) * CLng(ac5), 15)
mcprime = Shl(CLng(mc), 11)
' calculate every time
x1 = Shr((ut * CLng(ac5)), 15) - ac6_5prime
x2 = mcprime \ (x1 + CLng(md)) ' 1/160 of a degree C
' not needed if ok working in units of 1/160 of a degree.
t = Shr((x1 + x2 + 8), 4)
End Sub
Posted: 29 December 2010, 19:10 PM
by dkinzer
N.B., however, that the calibration values ac4, ac5 and ac6 are 16-bit unsigned values. The remaining calibration values are 16-bit signed values.