Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
Solved

# get a digit from a number without divide

Posted on 2006-10-30
Medium Priority
311 Views
Hello. I need a function that gets the digit from a number with only using *,^,+,- and the mod operator.

This function works, but it contains divide.

placement = to get the number from the end of the number to the right of the number

mod(floor(number/10^(placement-1)), 10)
0
Question by:m-jansen
[X]
###### Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

• Help others & share knowledge
• Earn cash & points
• 21
• 13
• 2
• +4

Author Comment

ID: 17833236
it's ok if it only works for numbers up to 10000
0

Author Comment

ID: 17833409
and floor is ok too
0

LVL 27

Expert Comment

ID: 17833486
For any positive munber N:

N - 10*mod( N, 10) will give you the last (units) digit.
0

LVL 27

Expert Comment

ID: 17833495
Sorry.  That should be just

mod( N, 10) will give you the last (units) digit.
0

Author Comment

ID: 17833543
How to get the seccond, third and fourth last?
0

LVL 27

Expert Comment

ID: 17833867
You can multiply by 10 to a negative exponent to accomplish the necessary division:

mod( 10^-1*(N - mod(N, 10))) will give you the second digit

mod( 10^-2*(N - mod(N, 100))) will give you the third digit
0

LVL 27

Expert Comment

ID: 17833961
Left out an argument:

mod( 10^-1*(N - mod(N, 10)), 10) will give you the second digit

mod( 10^-2*(N - mod(N, 100)), 10) will give you the third digit
0

LVL 27

Expert Comment

ID: 17834287
If p=1 refers to the units digit,     p=2 the tens digit,   ...

then the following formula should work for digits of any length.

mod( 10^(1-p)*(N - mod(N, 10^(p-1))), 10)    will give you the p-th digit

0

Author Comment

ID: 17834856
The right hand of ^ has to be a natural value. Is that possible?
0

LVL 27

Expert Comment

ID: 17835543
I don't think so.

Using the operators and functions you have specified, you can isolate any part of the number.

If   N= 8754

mod( N,     10) =   4
mod( N,   100) =  54
mod( N, 1000) = 754

mod( N,   100) =  54
mod( N, 1000)  - mod( N, 100) =  754 - 54 = 700

You need a division to extract the digit "7" from 700.

You can divide by 100, or multiply by 10^(-2), or take 10^(log(700)-2),
or shift the character string two places to the right.

But all of those operations are equivalent to division.

Where is this restriction against division coming from??
What are you trying to do??  Exactly.
0

LVL 69

Expert Comment

ID: 17835600
d-glitch,

It may be related to his Microchips question http://www.experts-exchange.com/Hardware/Microchips/Q_22042188.html, which you may know something about.
0

Author Comment

ID: 17835627
I try to get a specific number from an integer in order to use each digit in a four seven segment displays. :)
0

Author Comment

ID: 17835652
0

LVL 27

Expert Comment

ID: 17835754
That means that your number is stored in a set of registers in BCD format, and that you probably have lots of logic functions available.

If you have four digits, you have to set up at least a 2-bit counter (0-3) to drive the common (anode or cathode) for each digit.

And you have to set up a logic function for each segment.

I have done this in a CPLD using CUPL.  It is slightly hairy, but not really that hard.  I copied each digit to a 4-bit buffer register to simplify the logic for each segment.

You should thing about the timing before you start writing code.
0

LVL 27

Expert Comment

ID: 17835894
I don't know VHDL or Verilog.

But this is digital logic/multiplexing problem, not a mathmatical problem.

The logic goes something like this:

If Count = 0  copy Digit_1 to BCD_Buffer
If Count = 1  copy Digit_2 to BCD_Buffer
If Count = 2  copy Digit_3 to BCD_Buffer
If Count = 3  copy Digit_4 to BCD_Buffer

Anode_1 = Count:{0}
Anode_2 = Count:{1}
Anode_3 = Count:{2}
Anode_4 = Count:{3}

Seg_A = BCD_Buffer: {0, 2, 3, 5, 7, 8, 9}        /* Top Segment */
Seg_B = BCD_Buffer: {0, 1, 2, 3, 4, 7, 8, 9}    /* Upper Right Segment */
:
:
:
0

Author Comment

ID: 17836004
Thanks this changes my focus.
0

Author Comment

ID: 17836225
I can't see what kind of coding system I use. This is the table for one seven segment segment. DP is comma or point I think. A is LSB.

Decimal      A      B      C      D      E      F      G      DP
0      1      1      1      1      1      1      0      1
1      0      1      1      0      0      0      0      1
2      1      1      0      1      1      0      1      1
3      1      1      1      1      0      0      1      1
4      0      1      1      0      0      1      1      1
5      1      0      1      1      0      1      1      1
6      1      0      1      1      1      1      1      1
7      1      1      1      0      0      0      0      1
8      1      1      1      1      1      1      1      1
9      1      0      0      1      1      1      1      1
0

Author Comment

ID: 17836468
I have a 12 bit vector with normal binary coding. How to use this 12 bit  vector? Is the idea that I need to divide this vector into 4 parts and then use each 3 bit part to find out each number that is represented?
0

LVL 27

Expert Comment

ID: 17836705
Once again, on a higher level.  What exactly are you doing?

In particular, where does your 12-bit vector come from?

If you are counting something, that you need to display on a 7-segment display,
it would definitely be worth your while to use a BCD counter rather than a binary one.

If you don't have control of the input, i.e. you get a 12-bit binary number from someone
or somewhere else, then you probably have to convert the 12-bit binary data to BDC.

Once again, this is tedious but not difficult.  You need 15 or 16 equations for the BCD digits.

12-bit binary ==>  0-4095 so the MSB for the thousands digit is always 0.

0

LVL 27

Expert Comment

ID: 17836792
Another question:

Since you have asked about VHDL, I am assuming that this is a FPGA or CPLD project.  Correct?
If you have the option, it might be easier to do binary to BCD conversion with a microprocessor than with logic.

And how fast do the digits have to change?

0

Author Comment

ID: 17836860
I'm sorry I was a little to hasty there. The 12 bit vector I am talking about is an input and I think the format in this input is normal binary coding. This 12 bit input has untill now been converted to an integer (0-4096). And from that I have tried to extract each digit. And from that it would be possible to set each seven segment to the right value. But now I try to understand how to use this 12 bit value....

It's a FPGA project. The digits could change arround 50 hz.
0

Author Comment

ID: 17836869
How to use the 12 bit value without converting it to integer...
0

LVL 27

Expert Comment

ID: 17836956
You have a 12-bit input:   0-4095

You have a 4-digit seven-segment display.
Is it multiplexed, wth 7 segment lines and 4 common anode (or common cathode) lines?

Or does it have 28 (4x7) segment lines?

Another way to solve this problem is to use look-up tables.
You would need four 4095 x 8-bit tables, one for each digit.

1888 ==>  0000 0110     0111 1111     0111 1111     0111 1111

This might be the best way to program an FPGA.  I don't know for sure.
0

Author Comment

ID: 17837044
>Is it multiplexed, wth 7 segment lines and 4 common anode (or common cathode) lines?
Yes. It has 4 common cathode line and 7 segment lines and one extra segment line for a dot or point or something.
0

Author Comment

ID: 17837111
to see something on number one i must drive a 0 to the cathode that represents this number. and to light up the segments I must drive a 1 to these

cathode, segments
0111      1011 1111

would give me zero on the first digit from left
0

Author Comment

ID: 17837130
with the dot lighting as well...
0

LVL 27

Expert Comment

ID: 17837279
I am assuming this is a school project.  Is that correct?

Another way to convert 12-bit binary to 4-digit BCD is to count it.

You would load you input data into a binary down counter.
You would load 0000 into a BCD up counter.
Then you would clock both counters until the binary counter is all zeros.

This would take approximately 0.4 ms with a 10 MHz system clock.
The is negligible as far as the human eye is concerned.

Once you have the data converted to BCD, you would display it as I suggested in my earlier post.  [ 01:26PM EST ]

This approach will probably result in the simplest and shortest code.
0

Author Comment

ID: 17837311
Yes it is a scool project but I need some help because of my slow brain. You have been at big help so far.
0

Author Comment

ID: 17837593
the base clock speed is actually 10 MHz (Spartan2E)
0

Author Comment

ID: 17837920
I'll take a deeper look at this the next days.
0

LVL 27

Expert Comment

ID: 17838655
Happy to help in a strategic sense.
I won't be able to help much with the VHDL though.

One thing you might try to get you started is to try displaying the 12-bit vector
as three BCD characters.

I'm guessing that this project in on the order of 100 lines of code and several full days of work.
0

LVL 23

Expert Comment

ID: 17839717
You know you can do division with the ^  operator, right?

A^(-B)  =   1/A^B

So what's       number * 10^(-(placement - 1))     ?  :)

Shifting the decimal point to the left, truncating the stuff to the right, and taking mod 10 seems like a way to get any digit to me.
0

Author Comment

ID: 17840329
In my situation it's not legal to use negative constant on right side of arithmetic operator ^ or ** in VHDL
0

LVL 22

Expert Comment

ID: 17841132

There is no simple way to convert a binary number to decimal.

One kloodgy way would be to take your 12 bit input, store it into a count-downable register, and then count it down to zero while you count up a BCD register.  Not very fast but doable with just a few chips, so I assume it's programmable in VDHL.

If you must do it really fast, and it's only 12 bits, you could use a 14-bit address by 8-bit wide EROM  (16K bytes).  Feed in 12 bits of the number and two bits of the digit you want and voila, out the data lines come your 7-segments (plus an exta bit for whatever else you want to do).

0

LVL 12

Accepted Solution

jkmyoung earned 750 total points
ID: 17842946
mod(floor(number*0.1^(placement-1)), 10)
?
0

LVL 22

Expert Comment

ID: 17843158
It's easy to do if you don't mind iterating.

int placesize = 10^(placement-1)  /* assumes placement=1 means ones digit */

n = n mod (placesize * 10);   /* gets rid of digits above our desired digit. Don't care about smaller digits */
result = 0;
while (n >= placesize) {
n = n - placesize;
result = result + 1;
}

result is now the digit you're looking for.
0

LVL 22

Expert Comment

ID: 17843178
I don't see how he has mod but not divide available.  They're two sides to the same coin.

0

Author Comment

ID: 17843185
jkmyoung: yes that would work I think or....

n mod 10
for the last
n * 0.1 mod 10
for the seccond last
n * 0,01 mod 10
for the third last
n * 0,001 mod 10
for the seccond last
0

Author Comment

ID: 17843296
n * 0,001 mod 10
for the fourth last
0

Author Comment

ID: 17876243
jkmyoung: this gives me an answer to my problem. However it did not work in vhdl. Thanks everybody for the help. It's been too much.
0

## Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

How to Win a Jar of Candy Corn: A Scientific Approach! I love mathematics. If you love mathematics also, you may enjoy this tip on how to use math to win your own jar of candy corn and to impress your friends. As I said, I love math, but I guâ€¦
This article covers the basics of data encryption, what it is, how it works, and why it's important. If you've ever wondered what goes on when you "encrypt" data, you can look here to build a good foundation for your personal learning.
This is a video describing the growing solar energy use in Utah. This is a topic that greatly interests me and so I decided to produce a video about it.
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaacâ€¦
###### Suggested Courses
Course of the Month11 days, 15 hours left to enroll