>> and <<

Discussion about the ZBasic language including the System Library. If you're not sure where to post your message, do it here. However, do not make test posts here; that's the purpose of the Sandbox.
Post Reply
sturgessb
Posts: 287
Joined: 25 April 2008, 6:34 AM
Location: Norwich, UK

>> and <<

Post 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
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: >> and <<

Post 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;
- Don Kinzer
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post 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.
- Don Kinzer
sturgessb
Posts: 287
Joined: 25 April 2008, 6:34 AM
Location: Norwich, UK

Post 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
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post 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;
- Don Kinzer
mikep
Posts: 796
Joined: 24 September 2005, 15:54 PM

Post 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.
Mike Perks
sturgessb
Posts: 287
Joined: 25 April 2008, 6:34 AM
Location: Norwich, UK

Post by sturgessb »

hmmm i see

So what does that mean in this example, what would the code be?

Cheers

Ben
mikep
Posts: 796
Joined: 24 September 2005, 15:54 PM

Post 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
Mike Perks
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post 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.
- Don Kinzer
Post Reply