help with math.

Go To Last Post
24 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok I can't figure this out. I basically want to take two bytes and reduce it to one byte. So that ffff is ff and 0 is 0.

I tried this

unsigned char time =  ( ( v1 | (v2<<8) )  / 0xff);

I display by result with 8 lights. and I seems to get 0-256. So I figured just take 1 off. Well that is -1 to 255. What did I miss? is there a better way to do this.

Also ffff/ff is 0x101(257) ?
and ff00/ff is 0x100(256) which is more then ff so I must have something wrong.

Sorry for such a dumb question, but I know I need to learn a less here. More then likely something simple I should already know :roll: Is it because hex and binary use 0 as a bit where is that has no amount for decimal?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
and I seems to get 0-256

My guess is you get 0 to 255 (using 8 lights, anyway).

I don't understand exactly what you're trying to achieve - is the "reduction" merely throwing away the low order byte, or is it something else?

Chuck Baird

"I wish I were dumber so I could be more certain about my opinions. It looks fun." -- Scott Adams

http://www.cbaird.org

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry, I for get the proper name for this fraction. Proportional?

example:

100 is 100% of 100. So 10 is 10 percent of 10
80 is 80% of 100. So 8 is 8 percent of 10.
So I want my value to do the same,
x is 100% of FFFF, what is X proportionally to ff.

Do I need to divided by 101 and not ff. if so why

Last Edited: Sat. May 21, 2011 - 09:31 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Then, you simply want the high byte. If you shift everything right by 8, then the low byte will just disappear. You can do this magically by dividing by 256 and the optimizer will convert it to the appropriate right-shift.

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

but
00000011 11111111
should be 01111111 not 11111111 ?

Have I just confused us both?

Last Edited: Sat. May 21, 2011 - 09:37 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
but
11111111 11000000
should be 11111110 not 11111111 ?

Why?

Interesting - you changed it just as I posted. Now your answer should be 00000011.

Now I see you've edited it twice. You might want to stop doing that - just make a new post, so we're all talking about the same thing.

Chuck Baird

"I wish I were dumber so I could be more certain about my opinions. It looks fun." -- Scott Adams

http://www.cbaird.org

Last Edited: Sat. May 21, 2011 - 09:38 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, then if this is the case I dont really need my first byte? Should I just use the second? Sorry for that edit.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

right

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If by "first" you mean low order, yes. Just throw it away. As Jim says, divide by 256 (assuming you're starting with unsigned ints or longs) and you'll get what you want.

Chuck Baird

"I wish I were dumber so I could be more certain about my opinions. It looks fun." -- Scott Adams

http://www.cbaird.org

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have to get excel to spit this out. Because I wondered if that was the case.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok I think I understand this. Bit shifting 8 to the right is like dividing by one byte. Bit shifting 4 to the right is like dividing by 0F. Going to the left is like multiplication. Yes?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Bit shifting 8 to the right is like dividing by one byte. Bit shifting 4 to the right is like dividing by 0F. Going to the left is like multiplication. Yes?

1) Yes
2) No
3) Yes

Shifting 4 to the right is like dividing by 16 (0x10), not 15 (0x0f).

Work through it in base 10:

If I have 1234 and shift it 2 (decimal) places to the right, I end up with 12. That's the same as dividing by 10 to the power of 2 (2 = the number of shifted places), or 100. Tossing the remainder, of course.

Shifting one place to the right is dividing by 10^1, or 10; shifting zero places to the right is dividing by 10^0, or 1. As you say, shifting to the left is like multiplication, and it works the same way.

Chuck Baird

"I wish I were dumber so I could be more certain about my opinions. It looks fun." -- Scott Adams

http://www.cbaird.org

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Am I the only one who thinks the 'unsigned char' might be an issue? Like what happens when you take a unsigned char (byte) v2 and do v2<<8? You get 0. 0 ORed with v1 is v1. v1/0xff is 0 unless v1 == 0xff then it is 1 ( if you haven't included any casts which you didn't). What am I missing?

Smiley

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I did mention it above but it may have gotten lost in the noise (mostly of my making).

Quote:
(assuming you're starting with unsigned ints or longs)

Chuck Baird

"I wish I were dumber so I could be more certain about my opinions. It looks fun." -- Scott Adams

http://www.cbaird.org

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

S_K_U_N_X wrote:
example:

100 is 100% of 100. So 10 is 10 percent of 10
80 is 80% of 100. So 8 is 8 percent of 10.

No!

10 is 100 percent of 10. 10 percent of 10 is 1.

8 is 80 percent of 10. (8/10 = 0.8 or 0.8 X 100 = 80 percent)

Ross McKenzie ValuSoft Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

yeah valusoft, I goofed that but ka7ehk got the idea ;)

zbaird, thx, I see where I figure incorrectly.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

smileymicros wrote:
Like what happens when you take a unsigned char (byte) v2 and do v2<<8? You get 0.
No. v2 will be promoted to an int, and the result of the operation is an int too.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sternst wrote:
smileymicros wrote:
Like what happens when you take a unsigned char (byte) v2 and do v2<<8? You get 0.
No. v2 will be promoted to an int, and the result of the operation is an int too.
Are you sure you can rely on promotion? Maybe GCC, but is that a C Standard? To be safe you'd need to use casts and not rely on beneath the hood voodoo wouldn't you?

Smiley

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

smileymicros wrote:
but is that a C Standard?
Yes, it is.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
not rely on beneath the hood voodoo wouldn't you?
Absolutely nothing *wrong* with voodoo, AS LONG AS YOU WRITE SENSIBLE COMMENTS, so it's not indecipherable twaddle when you (or someone else) comes back in six months to update it ;)

On the other hand, if it's just a language function or artefact, then you should have access to the language reference (you can't borrow mine, I use [them] every day).

--greg
Still learning, don't shout at me, educate me.
Starting the fire is easy; the hardest part is learning how to keep the flame!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Are you sure you can rely on promotion?
Yes. In C, all operations on types smaller in size than int are done with automatic promotion to int. The problems with the hole concept here is first, he should be dividing by 0x100, not 0xff, and second, the result will always be just v2, so the whole operation is senseless.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Guys, the original query was:

unsigned char time =  ( ( v1 | (v2<<8) )  / 0xff);

While the variables will be promoted for the operations, the results is an 8-bit unsigned char. The results have nothing much to do with the value of v1 and v2 unless they just happen to yield 0xff in which case time is 1, otherwise time is 0 and it is 8-bits. It doesn't matter what the results are on the right side of the equation, those results will be de-promoted (truncated) back to 8 bits. I just went back to the standard and reread this part. Am I still missing something?

Smiley

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
While the variables will be promoted for the operations, the results is an 8-bit unsigned char.
Wrong. The results on the right side of the "=" will be a 16 bit integer. Only after the "=" is the result taken back down to 8 bit. So if v1 was 87 and v2 was 23, the result on the right side would be 23 (23 << 8 = 5888; 5888 + 87 = 5975; 5795 / 255 = 23).

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Okay, I see.

Smiley