LinuxQuestions.org
Visit Jeremy's Blog.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-07-2011, 08:07 PM   #1
raevin
Member
 
Registered: Jul 2004
Distribution: Arch Linux, Ubuntu
Posts: 80

Rep: Reputation: 16
Getting number of digits in uint64_t


Long story short, my issue is that I'm having a hard time trying to get the number of digits in a uint64_t variable. The reason I'm using this is I want to make sure I get x amount of digits inside of a variable before I use it, but since the higher the digits, the better the program is.

I currently use the following code, and it works, but my loop will never exit because the length is always 0:

Code:
/**
 * numbdigits()
 * number:      The number to evaluate  [in]
 *
 * Returns the number of digits found in a number.
 **/
uint64_t numdigits(uint64_t number){
        uint64_t tmp = number;

        uint64_t i = 0;

        if(number < 0)
                tmp = -tmp;

        while(tmp){
                tmp /= 10;
                i++;
        }

        return i;
}
Here's my code with the loop (that calls numdigits()):

Code:
uint64_t sized_num(int digits){
        uint64_t val = 2;
        uint64_t tmp = 0;
        uint64_t curd = 0; // Current digits

        while(curd <= digits){
                tmp = getrand(1, 2, 3, 4, 5, 6);
                val = tmp * tmp;
                curd = numdigits(val);
        }

        return val;
}
Anyone know what's going on? :/ getrand() returns a uint64_t as well (and works). The only way the while() loop ends without my intervention is if I do curd += numdigits(val) instead...but, that gives a false value as well.
 
Old 07-07-2011, 08:54 PM   #2
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
I think numdigits is correct (although checking if number is negative is useless because unsigned values can't be negative). What are you passing into sized_num? Do you realize that the max number of digits you can get is 19 = floor(log10(2^64)) 20 = ceiling(log10(2^64))?

Last edited by ntubski; 07-07-2011 at 09:09 PM. Reason: mixed up the digit formula
 
Old 07-07-2011, 09:03 PM   #3
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
You did not specify what parameter you gave to sized_num, nor did you tell us what getrand() returns.

Assuming getrand() picks one of its parameters at random, and returns it, then val will be between 1 and 36 every single time, and curd either 1 or 2. So, if you called sized_num(2) (or with any parameter larger than 2), the loop will obviously never end.

Also, uint64_t is a two's complement unsigned 64-bit integer, and therefore between 0 and 18446744073709551615 (inclusive). Exactly, not more, nor less. It can never be negative. Personally, I'd do a four-level comparison tree (since you only have 21 possible results -- 0, or 1 to 20 digits), in which case any input only takes four comparisons against fixed values to arrive at the correct result. Your code will need 21 comparisons in the function total, of course; just arranged as a binary tree.
 
Old 07-07-2011, 09:07 PM   #4
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Quote:
Originally Posted by ntubski View Post
What are you passing into sized_num? Do you realize that the max number of digits you can get is 19 = floor(log10(2^64))?
The number of digits function is actually ceil(log10(input)), as the OP returns 0 for zero input. If you count zero input also as one digit, then the function is 1+floor(log10(input)). In both cases the maximum number of digits for a 64-bit unsigned integer is 20, not 19.
 
Old 07-07-2011, 09:16 PM   #5
raevin
Member
 
Registered: Jul 2004
Distribution: Arch Linux, Ubuntu
Posts: 80

Original Poster
Rep: Reputation: 16
Sorry all.

What I'm passing to sized_num() is 300 (as I want 300 digits...which according to Nominal Animal, this isn't possible). This would explain, also, why it always return 19 or 20.

getrand() was a CMWC random-number generator that also returned a uint64_t, but I've since switched to a Mersenne Twister 64-bit random number generator (uint64_t).

Basically what I'm doing is trying to write a Dillie-Hellman Key Exchange system, and I'm trying to implement what can be best done as a purely random number generator for both the prime P, and secret of the user (so I can generate a secret key).

Perhaps I overly complicated this matter? I just didn't want to use srand()/rand(), and figured 64-bit integers would provide better encryption than a 32-bit integer would.
 
Old 07-07-2011, 09:41 PM   #6
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,780

Rep: Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081Reputation: 2081
Quote:
Originally Posted by raevin View Post
Perhaps I overly complicated this matter? I just didn't want to use srand()/rand(), and figured 64-bit integers would provide better encryption than a 32-bit integer would.
More like over simplifying: you need, at a minimum, 512-bit integers for a reasonable level of security (300 decimal digits is almost 1000 bits). You can use a library like gmp to get large integers, or, since I assume you are doing this for educational purposes, you may want to roll your own.
 
Old 07-07-2011, 09:50 PM   #7
raevin
Member
 
Registered: Jul 2004
Distribution: Arch Linux, Ubuntu
Posts: 80

Original Poster
Rep: Reputation: 16
Quote:
Originally Posted by ntubski View Post
More like over simplifying: you need, at a minimum, 512-bit integers for a reasonable level of security (300 decimal digits is almost 1000 bits). You can use a library like gmp to get large integers, or, since I assume you are doing this for educational purposes, you may want to roll your own.
Well, I'm trying to stay away from third-party libraries as much as possible, and am trying to roll my own...which is where I'm having issues it seems.
 
Old 07-07-2011, 11:50 PM   #8
raevin
Member
 
Registered: Jul 2004
Distribution: Arch Linux, Ubuntu
Posts: 80

Original Poster
Rep: Reputation: 16
New question in relation to this topic...

I've decided to go with a third-party library to make this task so much easier.

I know GMP supports integers bigger than 64, but is it possible with GLib as well? I can't find any information on how to do it, but there's nothing saying yes or no to this.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Identify and explain the major number, minor number, and revision number in Linux... turbomen Linux - Newbie 1 11-16-2010 02:48 AM
BASH - convert single digits to double digits. rickenbacherus Programming 7 05-07-2008 06:53 AM
grep and digits gawain Linux - Software 7 02-20-2008 02:13 AM
uint64_t + gcc + openDBX compilation error crapodino Programming 1 01-12-2008 04:47 PM
How to format a long double number in C++ to display as many digits as possible. TruongAn Programming 4 11-09-2005 10:11 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:04 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration