Solved

get a digit from a number without divide

Posted on 2006-10-30
40
301 Views
Last Modified: 2008-01-09
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
Comment
Question by:m-jansen
  • 21
  • 13
  • 2
  • +4
40 Comments
 

Author Comment

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

Author Comment

by:m-jansen
ID: 17833409
and floor is ok too
0
 
LVL 27

Expert Comment

by:d-glitch
ID: 17833486
For any positive munber N:

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

Expert Comment

by:d-glitch
ID: 17833495
Sorry.  That should be just

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

Author Comment

by:m-jansen
ID: 17833543
How to get the seccond, third and fourth last?
0
 
LVL 27

Expert Comment

by:d-glitch
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

by:d-glitch
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

by:d-glitch
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

by:m-jansen
ID: 17834856
The right hand of ^ has to be a natural value. Is that possible?
0
 
LVL 27

Expert Comment

by:d-glitch
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

by:Callandor
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

by:m-jansen
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

by:m-jansen
ID: 17835652
0
 
LVL 27

Expert Comment

by:d-glitch
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

by:d-glitch
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

by:m-jansen
ID: 17836004
Thanks this changes my focus.
0
 

Author Comment

by:m-jansen
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

by:m-jansen
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

by:d-glitch
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

by:d-glitch
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
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 

Author Comment

by:m-jansen
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

by:m-jansen
ID: 17836869
How to use the 12 bit value without converting it to integer...
0
 
LVL 27

Expert Comment

by:d-glitch
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

by:m-jansen
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

by:m-jansen
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

by:m-jansen
ID: 17837130
with the dot lighting as well...
0
 
LVL 27

Expert Comment

by:d-glitch
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

by:m-jansen
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

by:m-jansen
ID: 17837593
the base clock speed is actually 10 MHz (Spartan2E)
0
 

Author Comment

by:m-jansen
ID: 17837920
I'll take a deeper look at this the next days.
0
 
LVL 27

Expert Comment

by:d-glitch
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

by:Mysidia
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

by:m-jansen
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

by:grg99
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

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

Expert Comment

by:NovaDenizen
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

by:grg99
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

by:m-jansen
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

by:m-jansen
ID: 17843296
n * 0,001 mod 10
for the fourth last
0
 

Author Comment

by:m-jansen
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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Foreword (May 2015) This web page has appeared at Google.  It's definitely worth considering! https://www.google.com/about/careers/students/guide-to-technical-development.html How to Know You are Making a Difference at EE In August, 2013, one …
This article seeks to propel the full implementation of geothermal power plants in Mexico as a renewable energy source.
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now