In Solidity, is there a way I can convert my int to string ?
Example:
pragma solidity ^0.4.4;
contract someContract {
uint i;
function test() pure returns (string) {
return "Here and Now is Happiness!";
}
function love() pure returns(string) {
i = i +1;
return "I love " + functionname(i) + " persons" ;
}
}
What is functionname?Thanks!
solidity ^0.8.0
import "#openzeppelin/contracts/utils/Strings.sol";
Strings.toString(myUINT)
works for me.
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Strings.sol#L15-L35
UPDATE for Solidity 0.8.0:
The uint2str() function from https://github.com/provable-things/ethereum-api/blob/master/provableAPI_0.6.sol is now outdated, and will not work, but here is the updated code, that uses solidity 0.8.0:
(there was an Overflow bug in the last version but solidity <0.8.0 ignored that as it did not affect the answer, but that now throws an error)
byte was also changed to bytes1 and +,-,* and so on work like they would from the SafeMath library.
function uint2str(uint _i) internal pure returns (string memory _uintAsString) {
if (_i == 0) {
return "0";
}
uint j = _i;
uint len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint k = len;
while (_i != 0) {
k = k-1;
uint8 temp = (48 + uint8(_i - _i / 10 * 10));
bytes1 b1 = bytes1(temp);
bstr[k] = b1;
_i /= 10;
}
return string(bstr);
}
The two post here are giving the responses :
https://ethereum.stackexchange.com/questions/10811/solidity-concatenate-uint-into-a-string
https://ethereum.stackexchange.com/questions/10932/how-to-convert-string-to-int
function uintToString(uint v) constant returns (string str) {
uint maxlength = 100;
bytes memory reversed = new bytes(maxlength);
uint i = 0;
while (v != 0) {
uint remainder = v % 10;
v = v / 10;
reversed[i++] = byte(48 + remainder);
}
bytes memory s = new bytes(i + 1);
for (uint j = 0; j <= i; j++) {
s[j] = reversed[i - j];
}
str = string(s);
}
Regards
Concrete_Buddhas answer does not work in solidity 0.8.0. This is a revised version:
function uint2str(
uint256 _i
)
internal
pure
returns (string memory str)
{
if (_i == 0)
{
return "0";
}
uint256 j = _i;
uint256 length;
while (j != 0)
{
length++;
j /= 10;
}
bytes memory bstr = new bytes(length);
uint256 k = length;
j = _i;
while (j != 0)
{
bstr[--k] = bytes1(uint8(48 + j % 10));
j /= 10;
}
str = string(bstr);
}
The provable-things code suggested in the comments to the accepted answer worked for me, but my linter threw a warning namely: "uintToStr": Avoid assigning to function parameters. [security/no-assign-params]. The below changes the original code slightly to correct this (reassigning the parameter _i to another variable called number):
/// #notice converts number to string
/// #dev source: https://github.com/provable-things/ethereum-api/blob/master/oraclizeAPI_0.5.sol#L1045
/// #param _i integer to convert
/// #return _uintAsString
function uintToStr(uint _i) internal pure returns (string memory _uintAsString) {
uint number = _i;
if (number == 0) {
return "0";
}
uint j = number;
uint len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint k = len - 1;
while (number != 0) {
bstr[k--] = byte(uint8(48 + number % 10));
number /= 10;
}
return string(bstr);
}
If you need to optionally convert to scientific notation, for instance for a more compact number representation, here's a modifed version for that purpose:
function uintToString(uint v, bool scientific) public pure returns (string memory str) {
if (v == 0) {
return "0";
}
uint maxlength = 100;
bytes memory reversed = new bytes(maxlength);
uint i = 0;
while (v != 0) {
uint remainder = v % 10;
v = v / 10;
reversed[i++] = byte(uint8(48 + remainder));
}
uint zeros = 0;
if (scientific) {
for (uint k = 0; k < i; k++) {
if (reversed[k] == '0') {
zeros++;
} else {
break;
}
}
}
uint len = i - (zeros > 2 ? zeros : 0);
bytes memory s = new bytes(len);
for (uint j = 0; j < len; j++) {
s[j] = reversed[i - j - 1];
}
str = string(s);
if (scientific && zeros > 2) {
str = string(abi.encodePacked(s, "e", uintToString(zeros, false)));
}
}
Some unit tests:
function testUintToString() public {
Assert.equal(Utils.uintToString(0, true), '0', '0');
Assert.equal(Utils.uintToString(1, true), '1', '1');
Assert.equal(Utils.uintToString(123, true), '123', '123');
Assert.equal(Utils.uintToString(107680546035, true), '107680546035', '107680546035');
Assert.equal(Utils.uintToString(1e9, true), '1e9', '1e9');
Assert.equal(Utils.uintToString(1 ether, true), '1e18', '1 ether');
Assert.equal(Utils.uintToString(550e8, true), '55e9', '55e9');
}
The code snippets above are compatible with solidity 0.6.0.
While the accepted answer seems correct, it is quite inefficient on large numbers. Here is how I would do it:
function itoa32 (uint x) private pure returns (uint y) {
unchecked {
require (x < 1e32);
y = 0x3030303030303030303030303030303030303030303030303030303030303030;
y += x % 10; x /= 10;
y += x % 10 << 8; x /= 10;
y += x % 10 << 16; x /= 10;
y += x % 10 << 24; x /= 10;
y += x % 10 << 32; x /= 10;
y += x % 10 << 40; x /= 10;
y += x % 10 << 48; x /= 10;
y += x % 10 << 56; x /= 10;
y += x % 10 << 64; x /= 10;
y += x % 10 << 72; x /= 10;
y += x % 10 << 80; x /= 10;
y += x % 10 << 88; x /= 10;
y += x % 10 << 96; x /= 10;
y += x % 10 << 104; x /= 10;
y += x % 10 << 112; x /= 10;
y += x % 10 << 120; x /= 10;
y += x % 10 << 128; x /= 10;
y += x % 10 << 136; x /= 10;
y += x % 10 << 144; x /= 10;
y += x % 10 << 152; x /= 10;
y += x % 10 << 160; x /= 10;
y += x % 10 << 168; x /= 10;
y += x % 10 << 176; x /= 10;
y += x % 10 << 184; x /= 10;
y += x % 10 << 192; x /= 10;
y += x % 10 << 200; x /= 10;
y += x % 10 << 208; x /= 10;
y += x % 10 << 216; x /= 10;
y += x % 10 << 224; x /= 10;
y += x % 10 << 232; x /= 10;
y += x % 10 << 240; x /= 10;
y += x % 10 << 248;
}
}
function itoa (uint x) internal pure returns (string memory s) {
unchecked {
if (x == 0) return "0";
else {
uint c1 = itoa32 (x % 1e32);
x /= 1e32;
if (x == 0) s = string (abi.encode (c1));
else {
uint c2 = itoa32 (x % 1e32);
x /= 1e32;
if (x == 0) {
s = string (abi.encode (c2, c1));
c1 = c2;
} else {
uint c3 = itoa32 (x);
s = string (abi.encode (c3, c2, c1));
c1 = c3;
}
}
uint z = 0;
if (c1 >> 128 == 0x30303030303030303030303030303030) { c1 <<= 128; z += 16; }
if (c1 >> 192 == 0x3030303030303030) { c1 <<= 64; z += 8; }
if (c1 >> 224 == 0x30303030) { c1 <<= 32; z += 4; }
if (c1 >> 240 == 0x3030) { c1 <<= 16; z += 2; }
if (c1 >> 248 == 0x30) { z += 1; }
assembly {
let l := mload (s)
s := add (s, z)
mstore (s, sub (l, z))
}
}
}
}
Explanation
The itoa32 function converts a number below 10^32 into exactly 32 digits, padding it with zeros if necessary.
The itoa function calls the itoa32 up to three times to convert an arbitrary 256-bit number, then concatenates the results and removes leading zeros. It uses binary search to find out the exact number of leading zeros to be removed and removes leading zeros from a string in-place.
If your uint is coming from originally encoding a string into uint
string(abi.encode(myUint))
Related
I want to write a function to reverse one of two parts of number :
Input is: num = 1234567; part = 2
and output is: 1234765
So here is part that can be only 1 or 2
Now I know how to get part 1
int firstPartOfInt(int num) {
int ret = num;
digits = 1, halfDig = 10;
while (num > 9) {
ret = ret / 10;
digits++;
}
halfDigits = digits / 2;
for (int i = 1; i < halfDigits; i++) {
halfDigits *= 10;
}
ret = num;
while (num > halfDigits) {
ret = ret / 10;
}
return ret;
}
But I don't know how to get part 2 and reverse the number. If you post code here please do not use vector<> and other C++ feature not compatible with C
One way is to calculate the total number of digits in the number and then calculate a new number extracting digits from the original number in a certain order, complexity O(number-of-digits):
#include <stdio.h>
#include <stdlib.h>
unsigned reverse_decimal_half(unsigned n, unsigned half) {
unsigned char digits[sizeof(n) * 3];
unsigned digits10 = 0;
do digits[digits10++] = n % 10;
while(n /= 10);
unsigned result = 0;
switch(half) {
case 1:
for(unsigned digit = digits10 / 2; digit < digits10; ++digit)
result = result * 10 + digits[digit];
for(unsigned digit = digits10 / 2; digit--;)
result = result * 10 + digits[digit];
break;
case 2:
for(unsigned digit = digits10; digit-- > digits10 / 2;)
result = result * 10 + digits[digit];
for(unsigned digit = 0; digit < digits10 / 2; ++digit)
result = result * 10 + digits[digit];
break;
default:
abort();
}
return result;
}
int main() {
printf("%u %u %u\n", 0, 1, reverse_decimal_half(0, 1));
printf("%u %u %u\n", 12345678, 1, reverse_decimal_half(12345678, 1));
printf("%u %u %u\n", 12345678, 2, reverse_decimal_half(12345678, 2));
printf("%u %u %u\n", 123456789, 1, reverse_decimal_half(123456789, 1));
printf("%u %u %u\n", 123456789, 2, reverse_decimal_half(123456789, 2));
}
Outputs:
0 1 0
12345678 1 43215678
12345678 2 12348765
123456789 1 543216789
123456789 2 123459876
if understand this question well you need to reverse half of the decimal number. If the number has odd number of digits I assume that the first part is longer (for example 12345 - the first part is 123 the second 45). Because reverse is artihmetic the reverse the part 1 of 52001234 is 521234.
https://godbolt.org/z/frXvCM
(some numbers when reversed may wrap around - it is not checked)
int getndigits(unsigned number)
{
int ndigits = 0;
while(number)
{
ndigits++;
number /= 10;
}
return ndigits;
}
unsigned reverse(unsigned val, int ndigits)
{
unsigned left = 1, right = 1, result = 0;
while(--ndigits) left *= 10;
while(left)
{
result += (val / left) * right;
right *= 10;
val = val % left;
left /= 10;
}
return result;
}
unsigned reversehalf(unsigned val, int part)
{
int ndigits = getndigits(val);
unsigned parts[2], digits[2], left = 1;
if(ndigits < 3 || (ndigits == 3 && part == 2))
{
return val;
}
digits[0] = digits[1] = ndigits / 2;
if(digits[0] + digits[1] < ndigits) digits[0]++;
for(int dig = 0; dig < digits[1]; dig++) left *= 10;
parts[0] = val / left;
parts[1] = val % left;
parts[part - 1] = reverse(parts[part - 1], digits[part - 1]);
val = parts[0] * left + parts[1];
return val;
}
int main()
{
for(int number = 0; number < 40; number++)
{
unsigned num = rand();
printf("%u \tpart:%d\trev:%u\n", num,(number & 1) + 1,reversehalf(num, (number & 1) + 1));
}
}
My five cents.:)
#include <iostream>
int reverse_part_of_integer( int value, bool first_part = false )
{
const int Base = 10;
size_t n = 0;
int tmp = value;
do
{
++n;
} while ( tmp /= Base );
if ( first_part && n - n / 2 > 1 || !first_part && n / 2 > 1 )
{
n = n / 2;
int divider = 1;
while ( n-- ) divider *= Base;
int first_half = value / divider;
int second_half = value % divider;
int tmp = first_part ? first_half : second_half;
value = 0;
do
{
value = Base * value + tmp % Base;
} while ( tmp /= Base );
value = first_part ? value * divider + second_half
: first_half * divider +value;
}
return value;
}
int main()
{
int value = -123456789;
std::cout << "initial value: "
<< value << '\n';
std::cout << "First part reversed: "
<< reverse_part_of_integer( value, true ) << '\n';
std::cout << "Second part reversed: "
<< reverse_part_of_integer( value ) << '\n';
}
The program output is
initial value: -123456789
First part reversed: -543216789
Second part reversed: -123459876
Just for fun, a solution that counts only half the number of digits before reversing:
constexpr int base{10};
constexpr int partial_reverse(int number, int part)
{
// Split the number finding its "halfway"
int multiplier = base;
int abs_number = number < 0 ? -number : number;
int parts[2] = {0, abs_number};
while (parts[1] >= multiplier)
{
multiplier *= base;
parts[1] /= base;
}
multiplier /= base;
parts[0] = abs_number % multiplier;
// Now reverse only one of the two parts
int tmp = parts[part];
parts[part] = 0;
while (tmp)
{
parts[part] = parts[part] * base + tmp % base;
tmp /= base;
}
// Then rebuild the number
int reversed = parts[0] + multiplier * parts[1];
return number < 0 ? -reversed : reversed;
}
int main()
{
static_assert(partial_reverse(123, 0) == 123);
static_assert(partial_reverse(-123, 1) == -213);
static_assert(partial_reverse(1000, 0) == 1000);
static_assert(partial_reverse(1009, 1) == 109);
static_assert(partial_reverse(123456, 0) == 123654);
static_assert(partial_reverse(1234567, 0) == 1234765);
static_assert(partial_reverse(-1234567, 1) == -4321567);
}
I've been studying the Bitmap (.bmp) file format for a while now, trying to figure out how to structure the read function. The general idea is to support all the common compression types, be safe and still quick to load into a (custom) general in-memory image for further processing in a machine vision library.
With performance in mind, I figured it would be best to write an as efficient loop as possible for each bitcount + compression type constellation. Here's a snippet of how that looks for BI_RGB:
if (bmpi.biCompression == BI_RGB){
if (bmpi.biBitCount >= 24){
// Here, every byte is each channel's value (assuming order is GBR(A))
for (y = start_y; y != end_y; y += direction){
row = y * stride;
for (x = 0; x < stride; x += bpp){
index = row + x;
*(res->data++) = read_data[index + 2]; // R
*(res->data++) = read_data[index + 1]; // G
*(res->data++) = read_data[index]; // B
}
}
}
else if (bmpi.biBitCount == 16){
// Without a bitfield mask, it's assumed 555 (instead of the common 565) with the last bit discarded
for (y = start_y; y != end_y; y += direction){
row = y * stride;
for (x = 0; x < stride; x += bpp){
val = (WORD)&read_data[row + x];
*(res->data++) = map16to255[((val >> 10) & 31)]; // R
*(res->data++) = map16to255[((val >> 5) & 31)]; // G
*(res->data++) = map16to255[(val & 31)]; // B
}
}
}
else if (bmpi.biBitCount == 8){
for (y = start_y; y != end_y; y += direction){
row = y * stride;
for (x = 0; x < stride; x += bpp){
memcpy(res->data, &colors[read_data[row + x]], 3); // Copy RGB from color table
res->data += 3; // Increment
}
}
}
else if (bmpi.biBitCount == 4){
// 2 pixels per byte
for (y = start_y; y != end_y; y += direction){
row = y * stride;
for (x = 0; x < stride; x += bpp){
index = row + x;
memcpy(res->data, &colors[(read_data[index] & 15)], 3);
res->data += 3;
memcpy(res->data, &colors[(read_data[index] >> 4)], 3);
res->data += 3;
}
}
}
else{
// 8 pixels per byte
for (y = start_y; y != end_y; y += direction){
row = y * stride;
for (x = 0; x < stride; x += bpp){
index = row + x;
for (i = 0; i < 8; i++){
memcpy(res->data, &colors[((read_data[index] >> i) & 1)], 3);
res->data += 3;
}
}
}
}
}
It doesn't look pretty, to be honest.
Then I thought about assigning a function pointer and just write one loop but worry it would make it slower somehow. At least it would add a layer of obfuscation (of what is going on). I'd rather have bloated code if it clearly shows what is happening and what the intention is though
typedef void(*pxl_proc) (int index, BYTEP read_data, BYTEP in_data, PRGBQUAD colors);
//...
pxl_proc func = _24_rgb;
for (y = start_y; y != end_y; y += direction){
row = y * stride;
for (x = 0; x < stride; x += bpp){
func(row + x, read_data, res->data, colors);
}
}
I get the sense that this approach is unnecessarily specific and that there's a general way to process the bitmap while still being as quick, or quicker.
How should I be doing this? Is this "good enough" for a professional library?
Variable i toggles between 2 and 3 and multiplied into a, as in the following example:
a=2;
a=a*i // a=2*2=4 i=2
a=a*i // a=4*3=12 i=3
a=a*i // a=12*2=24 i=2
a=a*i // a=24*3=72 i=3
which goes on as long as a is < 1000.
How can I give the i two values sequentially as shown in the example?
int a = 2, i = 2;
while( a < 1000 )
{
a *= i;
i = 5 - i;
}
and many other ways.
You should be able to use a loop
int a = 2;
bool flip = true;
while (a < 1000)
{
a *= flip ? 2 : 3;
flip = !flip;
}
You can't have i be equal to two values at the same time. You can however make i alternate between 2 and 3 until a < 1000. Below is the code;
int a = 2;
int counter = 0;
while (a < 1000) {
if (counter % 2 == 0) {
a *= 2;
}
else {
a *= 3;
}
counter++;
}
Here's a quick solution that doesn't involve a conditional.
int c = 0;
while (a < 1000)
a *= (c++ % 2) + 2;
or even
for(int c = 0; a < 1000; c++)
a *= (c % 2) + 2;
The modulo is found, which results in either a 0 or a 1 and then shifted up by 2 resulting in either 2 or 3.
Here's another efficient way to do this.
#include <iostream>
using namespace std;
int main() {
int its_bacon_time;
int i = ++(its_bacon_time = 0);
int y = 18;
int z = 9;
bool flag = !false;
int sizzle;
typedef bool decision_property;
#define perhaps (decision_property)(-42*42*-42)
#ifdef perhaps
# define YUM -
# define YUMMM return
#endif
bool bacon = !(bool) YUM(sizzle = 6);
if(flag)
std::cout << "YEP" << std::endl;
while (flag) {
if (bacon = !bacon)
flag = !flag; // YUM()?
if (YUM((YUM-i)YUM(i*2))+1>=((0x1337|0xECC8)&0x3E8))
(*((int*)&flag)) &= 0x8000;
else
flag = perhaps;
std::cout << i << " ";
int multiplicative_factor = y / (bacon ? z : y);
int* temporal_value_indicator = &i;
(**(&temporal_value_indicator)) *=
(((((multiplicative_factor & 0x0001) > 0) ? sizzle : bacon) // ~yum~
<< 1) ^ (bacon? 0 : 15));
std::cout << (((((multiplicative_factor & 0x0001) > 0) ? sizzle : bacon) // ~yum~
<< 1) ^ (bacon? 0 : 15)) << std::endl;
}
YUMMM its_bacon_time;
}
Point is that you should probably try something yourself first before asking for something that is really simple to achieve.
int main()
{
int a = 2;
int multiplier;
for (int i = 0; a < 1000; ++i)
{
multiplier = (i % 2) ? 2 : 3;
a *= multiplier;
}
}
I've tried to check whether a number is a palindrome with the following code:
unsigned short digitsof (unsigned int x)
{
unsigned short n = 0;
while (x)
{
x /= 10;
n++;
}
return n;
}
bool ispalindrome (unsigned int x)
{
unsigned short digits = digitsof (x);
for (unsigned short i = 1; i <= digits / 2; i++)
{
if (x % (unsigned int)pow (10, i) != x % (unsigned int)pow (10, digits - 1 + i))
{
return false;
}
}
return true;
}
However, the following code isn't able to check for palindromes - false is always returned even if the number is a palindrome.
Can anyone point out the error?
(Please note: I'm not interested to make it into a string and reverse it to see where the problem is: rather, I'm interested to know where the error is in the above code.)
I personally would just build a string from the number, and then treat it as a normal palindrome check (check that each character in the first half matches the ones at length()-index).
x % (unsigned int)pow (10, i) is not the ith digit.
The problem is this:
x % (unsigned int)pow (10, i)
Lets try:
x =504405
i =3
SO I want 4.
x % 10^3 => 504405 %1000 => 405 NOT 4
How about
x / (unsigned int)pow (10, i -1) % 10
Just for more info! The following two functions are working for me:
double digitsof (double x)
{
double n = 0;
while (x > 1)
{
x /= 10;
n++;
}
return n;
}
bool ispalindrome (double x)
{
double digits = digitsof (x);
double temp = x;
for(double i = 1; i <= digits/2; i++)
{
float y = (int)temp % 10;
cout<<y<<endl;
temp = temp/10;
float z = (int)x / (int)pow(10 , digits - i);
cout<<(int)z<<endl;
x = (int)x % (int)pow(10 , digits - i);
if(y != z)
return false;
}
return true;
}
Code to check if given number is palindrome or not in JAVA
import java.util.*;
public class HelloWorld{
private static int countDigits(int num) {
int count = 0;
while(num>0) {
count++;
num /= 10;
}
return count;
}
public static boolean isPalin(int num) {
int digs = HelloWorld.countDigits(num);
int divderToFindMSD = 1;
int divderToFindLSD = 1;
for (int i = 0; i< digs -1; i++)
divderToFindMSD *= 10;
int mid = digs/2;
while(mid-- != 0)
{
int msd = (num/divderToFindMSD)%10;
int lsd = (num/divderToFindLSD)%10;
if(msd!=lsd)
return false;
divderToFindMSD /= 10;
divderToFindLSD *= 10;
}
return true;
}
public static void main(String []args) {
boolean isPalin = HelloWorld.isPalin(1221);
System.out.println("Results: " + isPalin);
}
}
I have done this with my own solution which is restricted with these conditions
Do not convert int to string.
Do not use any helper function.
var inputNumber = 10801
var firstDigit = 0
var lastDigit = 0
var quotient = inputNumber
while inputNumber > 0 {
lastDigit = inputNumber % 10
var tempNum = inputNumber
var count = 0
while tempNum > 0 {
tempNum = tempNum / 10
count = count + 1
}
var n = 1
for _ in 1 ..< count {
n = n * 10
}
firstDigit = quotient / n
if firstDigit != lastDigit {
print("Not a palindrome :( ")
break
}
quotient = quotient % n
inputNumber = inputNumber / 10
}
if firstDigit == lastDigit {
print("It's a palindrome :D :D ")
}
I've been trying to implement the algorithm from wikipedia and while it's never outputting composite numbers as primes, it's outputting like 75% of primes as composites.
Up to 1000 it gives me this output for primes:
3, 5, 7, 11, 13, 17, 41, 97, 193, 257, 641, 769
As far as I know, my implementation is EXACTLY the same as the pseudo-code algorithm. I've debugged it line by line and it produced all of the expected variable values (I was following along with my calculator). Here's my function:
bool primeTest(int n)
{
int s = 0;
int d = n - 1;
while (d % 2 == 0)
{
d /= 2;
s++;
}
// this is the LOOP from the pseudo-algorithm
for (int i = 0; i < 10; i++)
{
int range = n - 4;
int a = rand() % range + 2;
//int a = rand() % (n/2 - 2) + 2;
bool skip = false;
long x = long(pow(a, d)) % n;
if (x == 1 || x == n - 1)
continue;
for (int r = 1; r < s; r++)
{
x = long(pow(x, 2)) % n;
if (x == 1)
{
// is not prime
return false;
}
else if (x == n - 1)
{
skip = true;
break;
}
}
if (!skip)
{
// is not prime
return false;
}
}
// is prime
return true;
}
Any help would be appreciated D:
EDIT: Here's the entire program, edited as you guys suggested - and now the output is even more broken:
bool primeTest(int n);
int main()
{
int count = 1; // number of found primes, 2 being the first of course
int maxCount = 10001;
long n = 3;
long maxN = 1000;
long prime = 0;
while (count < maxCount && n <= maxN)
{
if (primeTest(n))
{
prime = n;
cout << prime << endl;
count++;
}
n += 2;
}
//cout << prime;
return 0;
}
bool primeTest(int n)
{
int s = 0;
int d = n - 1;
while (d % 2 == 0)
{
d /= 2;
s++;
}
for (int i = 0; i < 10; i++)
{
int range = n - 4;
int a = rand() % range + 2;
//int a = rand() % (n/2 - 2) + 2;
bool skip = false;
//long x = long(pow(a, d)) % n;
long x = a;
for (int z = 1; z < d; z++)
{
x *= x;
}
x = x % n;
if (x == 1 || x == n - 1)
continue;
for (int r = 1; r < s; r++)
{
//x = long(pow(x, 2)) % n;
x = (x * x) % n;
if (x == 1)
{
return false;
}
else if (x == n - 1)
{
skip = true;
break;
}
}
if (!skip)
{
return false;
}
}
return true;
}
Now the output of primes, from 3 to 1000 (as before), is:
3, 5, 17, 257
I see now that x gets too big and it just turns into a garbage value, but I wasn't seeing that until I removed the "% n" part.
The likely source of error is the two calls to the pow function. The intermediate results will be huge (especially for the first call) and will probably overflow, causing the error. You should look at the modular exponentiation topic at Wikipedia.
Source of problem is probably here:
x = long(pow(x, 2)) % n;
pow from C standard library works on floating point numbers, so using it is a very bad idea if you just want to compute powers modulo n. Solution is really simple, just square the number by hand:
x = (x * x) % n