简体   繁体   中英

Generate any random NSInteger with exactly 18 digits

I tried this:

NSInteger numberFinal = 100000000000000000 + ((float)arc4random() / UINT32_MAX) * (999999999999999999 - 100000000000000000);

but it returns zero... I don't want to specify the range, but just want any number with 18 digits...

For your requirement, as @duDE mentioned you can't use a NSInteger to save 18 digit number, but there is a solution using NSString .

NSString *eighteenDigitNumberString = [[NSNumber numberWithInt:1 + arc4random_uniform(9)] stringValue];

for (int i = 0; i < 17; i++) {

    eighteenDigitNumberString = [eighteenDigitNumberString stringByAppendingString:[[NSNumber numberWithInt:arc4random_uniform(10)] stringValue]];
}

NSLog(@"eighteenDigitNumberString : %@", eighteenDigitNumberString);

There we go, no need to explain everything is straightforward.

EDITED: if you really want a long long value you can do so:

long long eighteenDigitNumberLongLong = [eighteenDigitNumberString longLongValue];  

EDITED: To avoid the leading 0 the initial string has been initiated with a non-zero number and the loop is running only 17 times.

As the maximum value of an NSInteger is NSIntegerMax , you cann't use NSInteger for your purpose:

enum {
   NSNotFound = NSIntegerMax
};

Prior to OS X v10.5, NSNotFound was defined as 0x7fffffff . This is 2147483647 (decimal).

If you need "any number" with 18 digits (as @A-Live assumes), you can take NSFloat for example.

A 18 digit integer will require a long long type.

Create two 9 digit random numbers, multiple one by 10^9 and add to the other.

const u_int32_t digits9 = 1000000000;
u_int32_t ms = arc4random_uniform(digits9);
u_int32_t ls = arc4random_uniform(digits9);
unsigned long long random18 = ((unsigned long long)ms * digits9) + ls;

NSLog(@"Example random18: %018llu", random18);

Output:

Example random18: 501895974656079554

If the number must have a leading non zero digit:

const u_int32_t digits81 = 100000000;
const u_int32_t digits89 = 900000000;
const u_int32_t digits9 = 1000000000;

u_int32_t ms = arc4random_uniform(digits89) + digits81;
u_int32_t ls = arc4random_uniform(digits9);
unsigned long long random18 = ((unsigned long long)ms * digits9) + ls;

If you need strictly 18 digits it would be better to use this code:

NSString *stringNumber = [NSString string];

for (int i = 0; i < 18; i++) {
    if (i == 0) {   
        stringNumber = [stringNumber stringByAppendingString:[NSString stringWithFormat:@"%@", @(arc4random_uniform(9) + 1)]];
    } else {
        stringNumber = [stringNumber stringByAppendingString:[NSString stringWithFormat:@"%@", @(arc4random_uniform(10))]];
    }
}

long long value = stringNumber.longLongValue;

You need the first condition because with the possibility of 0.1 you may receive 0 as the first digit, then your 18-digit integer would become 17-digit, with 0.01 possibility - 16-digit integer etc.

You're getting into unsigned long long territory...

#define ARC4RANDOM_MAX      0x100000000

float val = ((double)arc4random() / ARC4RANDOM_MAX);
unsigned long long numberToAdd = val * (900000000000000000-1);
unsigned long long numberFinal = 100000000000000000 + numberToAdd;

NSLog( @"value = %llu", numberFinal);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM