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 ?

Code: Select all

Shr&#40;val, 15&#41;
However, if it is a 16-bit value, it may be more efficient to write it as

Code: Select all

IIF&#40;CBool&#40;val And &H8000&#41;, 1, 0&#41;

Posted: 29 December 2010, 14:52 PM
by dkinzer
Or, considering the entire expression:

Code: Select all

If CBool&#40;ac5 And &H8000&#41; Then
  x1 = &#40;ut - ac6&#41;
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 = &#40;ut - ac6&#41; * ac5 >> 15;
x2 = &#40;mc << 11&#41; / &#40;x1 + md&#41;;
b5 = x1 + x2;
temperature = &#40;b5 + 8&#41; >> 4;

Would become....

Code: Select all

X1 = &#40;UT - Clng&#40;ac6&#41;&#41; * Clng&#40;Shr&#40;ac5,15&#41;&#41;
X2 = Clng&#40;Shl&#40;mc,11&#41;&#41;  \ &#40;X1 + Clng&#40;md&#41;&#41;
B5 = X1 + X2
T = Shr&#40;&#40;B5 + 8&#41;, 4&#41;
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&#40;&#40;ut - CLng&#40;ac6&#41;&#41; * CLng&#40;ac5&#41;, 15&#41;
x2 = Shl&#40;CLng&#40;mc&#41;, 11&#41; \ &#40;x1 + CLng&#40;md&#41;&#41;

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&#40;&#40;B5 + 8&#41;, 4&#41;
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&#40;&#41;
	' temporary values
	Dim x1 as Long, x2 as Long

	' calculate once from calibration values
	ac6_5prime = Shr&#40;CLng&#40;ac6&#41; * CLng&#40;ac5&#41;, 15&#41;
	mcprime = Shl&#40;CLng&#40;mc&#41;, 11&#41;

	' calculate every time
	x1 = Shr&#40;&#40;ut * CLng&#40;ac5&#41;&#41;, 15&#41; - ac6_5prime
	x2 = mcprime \ &#40;x1 + CLng&#40;md&#41;&#41;    ' 1/160 of a degree C

	' not needed if ok working in units of 1/160 of a degree.
	t = Shr&#40;&#40;x1 + x2 + 8&#41;, 4&#41;
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.