Strtol implementation different behaviour on 32 and 64 bit machine - 32bit-64bit

#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <tgmath.h>
#include <limits.h>
#include <stdbool.h>
#include <errno.h>
#define NEGATIVE -1
#define POSITIVE 1
#define OCTAL 8
#define DECIMAL 10
#define HEXADECIMAL 16
#define BASE_MIN 2
#define BASE_MAX 36
long int strtol (const char * str, char ** endPtr, int base)
{
if(base < 0 || base == 1 || base > BASE_MAX)
{
errno = EINVAL;
return 0L;
}
else
{
bool conversion = true;
int i = 0, sign = POSITIVE, save;
while(isspace(*(str + i)))
i++;
if(*(str + i) == '\0')
{
conversion = false;
save = i;
}
if(*(str + i) == '-')
{
sign = NEGATIVE;
i++;
}
else if(*(str + i) == '+')
i++;
if(base == 0) // find out base
{
if(*(str + i) == '0')
{
if(toupper(*(str + i + 1)) == 'X')
{
base = HEXADECIMAL;
i++;
}
else
base = OCTAL;
i++;
}
else
base = DECIMAL;
}
else if(base == OCTAL)
{
if(*(str + i) == '0')
i++;
}
else if(base == HEXADECIMAL)
{
if(*(str + i) == '0')
if(*(str + i + 1) == 'x' || *(str + i + 1) == 'X')
i += 2;
}
int start = i, end, exp, check = i;
long int long_int, sum, multiplier;
if(conversion) // find out the correct part of the string corresponding to the number
{
if(base < DECIMAL)
{
while(*(str + i) >= '0' && *(str + i) < base + '0') // numbers from 0 to base - 1
i++;
}
else if(base == DECIMAL)
{
while(*(str + i) >= '0' && *(str + i) <= '9') // numbers from 0 to 9
i++;
}
else
{
while((*(str + i) >= '0' && *(str + i) <= '9') || (toupper(*(str + i)) >= 'A' && toupper(*(str + i)) < 'A' + base - 10))
i++;// numbers from 0 to 9 and uper and lowercase letters from a to a + base - 11
}
}
if(i == check && conversion) //no digits at all
{
conversion = false;
save = i;
}
else if(endPtr != NULL && conversion) // assign pointer
*endPtr = (char *) (str + i);
if(conversion)
{
for(end = i - 1, exp = 0, long_int = 0L; end >= start; end--, exp++)
{
multiplier = pow(base, exp);
sum = 0L;
if(*(str + end) >= '0' && *(str + end) <= '9')
sum = (*(str + end) - '0') * multiplier;
else if(*(str + end) >= 'A' && *(str + i) <= (base == BASE_MAX ? 'Z' : 'F'))
sum = (*(str + end) - 'A' + 10) * multiplier;
else if(*(str + end) >= 'a' && *(str + i) <= (base == BASE_MAX ? 'z' : 'f'))
sum = (*(str + end) - 'a' + 10) * multiplier;
if(long_int <= LONG_MIN + sum)
{
errno = ERANGE;
return LONG_MIN;
}
if(long_int >= LONG_MAX - sum)
{
errno = ERANGE;
return LONG_MAX;
}
else
long_int += sum;
}
return sign * long_int;
}
else
{
if(endPtr != NULL)
{// if base is 16 we check if the string given is not in the form 0xIncorrect string in that way we need to return xIncorrect part of the string
if(base == HEXADECIMAL && save >= 2 && toupper(*(str + save - 1)) == 'X' && *(str + save - 2) == '0')
*endPtr = (char *) str + save - 1;
else if(base == OCTAL && save >= 1 && *(str + save - 1) == '0')
*endPtr = (char *) str + save;// if the string is of base 8 and in the form 0incorrect string
else //then we return everything after the 0 as the endptr string
*endPtr = (char *) str;//in other cases no conversion was done so we return original pointer
}
return 0L;
}
}
}
I've got problem with writing implementation of strtol() function. The thing is i compiled it on 64 bit machine and the output was correct but today i checked it on another machine that is 32-bit and something got wrong. 32-bit machine showed the result that for example string "7FFFFFFF" is out of range when on 64-bits the results is that strtol succeded which is the same as for th standard function. I also checked errno value and for 32-bit machine it's set to ERANGE which shouldn't be and it's not not on 64-bit. I have program that checks if your implementation gives the same output as the standard one for different strings. I spent few hours looking for possible bug but i'm out of ideas? Any tips?

Related

Can someone explain the mistake in this code? Leetcode 44 Wildcard Matching

Can Someone explain what is wrong in this code ?
It is failing on testcase s = "aa" and p = "*".
I have followed recursion and dynamic programming code here
Leetcode 44 Wildcard Matching
class Solution {
public boolean isMatch(String s, String p) {
int n = s.length();
int m = p.length();
int[][] dp = new int[n][m];
for(int[] it : dp)
Arrays.fill(it, -1);
return solve(n-1 , m-1, s ,p , dp);
}
public boolean solve(int i, int j, String s, String p, int[][] dp){
if(i < 0 && j < 0) return true;
if(i < 0 && j >=0){
while(j>=0){
if(p.charAt(j) + "" == "*") j--;
else return false;
}
return true;
}
if(j < 0 && i >=0) return false;
if(dp[i][j] != -1){
if(dp[i][j]==1) return true;
return false;
}
if(s.charAt(i) == p.charAt(j) || p.charAt(j) + "" == "?"){
boolean temp = solve(i-1,j-1,s,p,dp);
if(temp == false) dp[i][j] = 0;
else
dp[i][j] = 1;
return temp;
}
if(p.charAt(j) + "" == "*"){
boolean temp = solve(i-1,j,s,p,dp) || solve(i,j-1,s,p,dp);
if(temp == false)
dp[i][j] = 0;
else
dp[i][j] = 1;
return temp;
}
dp[i][j] = 0;
return false;
}
}

Trouble when rendering voxels with pathtracing

I'm currently working on a pathtracer in c and open cl.
I'm using this algorithm for rendering. The first collision works well, however, from the second collision onwards there is a dark shadow on the lower side of the voxels.
This is the color of the voxel the initial ray hits:
result
This is the color of the voxel that the second ray hits:
result
And this is the result after rendering to a depth of 1000:
result
This is the code I used (openCL):
int cast_ray(Renderer *r, Ray ray, float3 *hitPos, int3 *normal, Material *material) {
int3 voxel = convert_int3(ray.origin);
int3 step = {
(ray.direction.x >= 0) ? 1 : -1,
(ray.direction.y >= 0) ? 1 : -1,
(ray.direction.z >= 0) ? 1 : -1
};
float3 tMax = {
(ray.direction.x != 0) ? (voxel.x + step.x - ray.origin.x) / ray.direction.x : MAXFLOAT,
(ray.direction.y != 0) ? (voxel.y + step.y - ray.origin.y) / ray.direction.y : MAXFLOAT,
(ray.direction.z != 0) ? (voxel.z + step.z - ray.origin.z) / ray.direction.z : MAXFLOAT
};
float3 tDelta = {
(ray.direction.x != 0) ? 1 / ray.direction.x * step.x : MAXFLOAT,
(ray.direction.y != 0) ? 1 / ray.direction.y * step.y : MAXFLOAT,
(ray.direction.z != 0) ? 1 / ray.direction.z * step.z : MAXFLOAT
};
int side;
while(1) {
if(tMax.x < tMax.y) {
if(tMax.x < tMax.z) {
voxel.x += step.x;
tMax.x += tDelta.x;
side = 0;
} else {
voxel.z += step.z;
tMax.z += tDelta.z;
side = 2;
}
} else {
if(tMax.y < tMax.z) {
voxel.y += step.y;
tMax.y += tDelta.y;
side = 1;
} else {
voxel.z += step.z;
tMax.z += tDelta.z;
side = 2;
}
}
if(out_of_scene(r, voxel))
return 0;
MaterialID id = get_material_ID(r, voxel);
if(id == 0)
continue;
*material = get_material(r, id);
switch(side) {
case 0:
hitPos->x = (float)voxel.x;
hitPos->y = ray.origin.y + (hitPos->x - ray.origin.x) * ray.direction.y / ray.direction.x;
hitPos->z = ray.origin.z + (hitPos->x - ray.origin.x) * ray.direction.z / ray.direction.x;
*normal = (int3){-step.x, 0, 0};
break;
case 1:
hitPos->y = (float)voxel.y;
hitPos->x = ray.origin.x + (hitPos->y - ray.origin.y) * ray.direction.x / ray.direction.y;
hitPos->z = ray.origin.z + (hitPos->y - ray.origin.y) * ray.direction.z / ray.direction.y;
*normal = (int3){0, -step.y, 0};
break;
case 2:
hitPos->z = (float)voxel.z;
hitPos->y = ray.origin.y + (hitPos->z - ray.origin.z) * ray.direction.y / ray.direction.z;
hitPos->x = ray.origin.x + (hitPos->z - ray.origin.z) * ray.direction.x / ray.direction.z;
*normal = (int3){0, 0, -step.z};
break;
}
return 1;
}
}
float3 get_color(Renderer *r, Ray ray) {
float3 mask = 1;
float3 color = 0;
int maxDepth = 1000;
for(int i = 0; i < maxDepth; i++) {
float3 hitPos;
int3 iNormal;
Material material;
if(cast_ray(r, ray, &hitPos, &iNormal, &material)) {
float3 fNormal = convert_float3(iNormal);
if(material.type == 1) {
color = mask * material.color;
break;
} else if(material.type == 2) {
float3 direction = fNormal + random_unit_vector(r->rng);
ray = (Ray){hitPos, direction};
mask *= material.color;
} else if(material.type == 3) {
float3 direction = reflection_dir(ray.direction, fNormal) + random_unit_vector(r->rng) * material.fuzzyness;
ray = (Ray){hitPos, direction};
mask = mask * (1 - material.tint) + mask * material.color * material.tint;
}
} else {
color = mask * r->bgColor;
break;
}
// if(i == 1)
// return material.color;
}
return color;
}
I think that the problem is that the new origin of the ray is somehow not correct, but I can't find a way to fix it.

Explanation for crashing at n = 16

I am having a trouble in completing a homework of mine in C.The task is given an integer n print all the binary numbers with the length n that do not have 2 consecutive zeros int them and that includes leading zeros, note that at least one of the functions has to be recursive. Here is an example if n is 4 then the binary number 10 is treated 0010 and therefore wont be printed because it has 2 leading zeros. My problem is that my code crashes if n = 16 and I do not know why even though I have done a lot of debugging. Here is my code, Thanks for any help here.
void binaries_n_digits_no_00(int n)
{
if(n < 0)
{
return;
}
print_binaries_n_digits_no_00(0,n);
}
void print_binaries_n_digits_no_00(long int current_binary_index,int n)
{
int num_of_leading_zeros;
if((current_binary_index > (power(2,n) - 1)) || n == 0)
{
return;
}
num_of_leading_zeros = n - binary_num_length(current_binary_index);
if((binary_not_contain_00(current_binary_index) == 1) &&
(num_of_leading_zeros == 1 || num_of_leading_zeros == 0)){
if(current_binary_index == 0 && n == 1)
{
printf("\n0");
}
else if(num_of_leading_zeros == 1)
{
if(current_binary_index != 0)
{
printf("\n0");
print_binary(current_binary_index);
}
}
else{
printf("\n");
print_binary(current_binary_index);
}
}
print_binaries_n_digits_no_00(current_binary_index+1,n);
}
int binary_not_contain_00(long int num)
{
if(num/2 == 0)
{
return 1;
}
if(((num%2) == 0) && (((num/2) % 2) == 0))
{
return 0;
}
return binary_not_contain_00(num/2);
}
void print_binary(long int num)
{
if(num > 1)
{
print_binary(num/2);
}
printf("%d",num%2);
}
int binary_num_length(long int num)
{
if(num <= 1)
{
return 1;
}
else{
return (1 + binary_num_length(num/2));
}
}
long int power(int m, int n)
{
if(n == 0)
{
return 1;
}
return m * power(m,n-1);
}

Algorithm implemented with openCL working till size exceeds 768

I've implemented sorting algorithm using openCL. Its using one work group per array to sort (arrays are connected in __global float *array, all have the same size).
Im testing results using 200 random arrays and result are deterministic.
With one parameter, its working correctly till array size exceeds of array 768
With two parameters, its working correctly till arrays size exceeds 768
With three parameters, its working correctly till arrays size exceeds 317
What could be the reason of correct processing of just 768 (CL_KERNEL_WORK_GROUP_SIZE returns 1024 elements). Is it some memory constraints? What is the best way of invastigation such issue?
Gpu specs (4th answer):
Kernel code below:
__kernel void assort(
__global float *array,
__local float *currentOutput,
__local float *stimulations,
__local int *noOfValuesAdded,
__local float *addedValue,
__local float *positionToInsert,
__local int *activatedIdx,
__local float *range,
int size
) {
int id = get_local_id(0);
int gid = get_group_id(0);
if (id == 0)
{
if (array[gid*size]<array[gid*size+1])
{
currentOutput[0] = array[gid*size];
currentOutput[1] = array[gid*size + 1];
}
else
{
currentOutput[1] = array[gid*size];
currentOutput[0] = array[gid*size + 1];
}
noOfValuesAdded[0] = 2;
}
barrier(CLK_LOCAL_MEM_FENCE);
for (int i = 2; i < size; i++)
{
int maxIdx = noOfValuesAdded[0] - 1;
if (id == 0)
{
addedValue[0] = array[gid*size + i];
positionToInsert[0] = -100.0f;
activatedIdx[0] = -2;
range[0] = currentOutput[maxIdx] - currentOutput[0];
}
barrier(CLK_LOCAL_MEM_FENCE);
if (id < noOfValuesAdded[0])
{
if (id == 0)
{
stimulations[id] = (currentOutput[maxIdx] - addedValue[0]) / range[0];
float stimulation = stimulations[id];
if ( fabs(stimulation - 1.0f) < 0.000001)
activatedIdx[0] = 0;
else if (stimulation > 1.0f)
{
activatedIdx[0] = -1;
}
}
else if (id == maxIdx)
{
stimulations[maxIdx] = (addedValue[0] - currentOutput[0]) / range[0];
float stimulations = (addedValue[0] - currentOutput[0]) / range[0];
if ( fabs(stimulations - 1.0f) < 0.000001 )
activatedIdx[0] = maxIdx;
else
if (stimulations > 1)
activatedIdx[0] = maxIdx + 1;
}
else
{
stimulations[id] = 1.0f - (fabs((currentOutput[id] - addedValue[0])) / range[0]);
if ( fabs(stimulations[id] - 1.0f) < 0.000001)
activatedIdx[0] = id;
}
}
barrier(CLK_LOCAL_MEM_FENCE);
if (activatedIdx[0] == -2 && id < noOfValuesAdded[0])
{
if (noOfValuesAdded[0] == 2)
{
positionToInsert[0] = 0.9f;
}
else if (id != 0 &&
id != maxIdx &&
stimulations[id] >= stimulations[(id - 1)] &&
stimulations[id] >= stimulations[(id + 1)] )
{
if ((1.0f - (fabs(currentOutput[(id - 1)] - currentOutput[id]) / range[0]) ) < stimulations[(id - 1)])
positionToInsert[0] = (float)id - 0.1f;
else
positionToInsert[0] = (float)id + 0.9f;
}
}
barrier(CLK_LOCAL_MEM_FENCE);
if (activatedIdx[0] == -2)
{
if (id == 0 && positionToInsert[0] < -90.0f) // default value maintained
{
if (stimulations[0] > stimulations[1])
positionToInsert[0] = 0.9f;
else
positionToInsert[0] = (float)maxIdx - 0.1f;
}
}
else
{
if (activatedIdx[0] == -1)
positionToInsert[0] = -0.1f;
else if (activatedIdx[0] == (maxIdx + 1))
{
positionToInsert[0] = (float)maxIdx + 0.9f;
}
else
{
currentOutput[activatedIdx[0]] = addedValue[0];
}
}
barrier(CLK_LOCAL_MEM_FENCE);
if (positionToInsert[0] > -50.0f) // default value changed
{
float temp = 0.0f;
if ((float)id>positionToInsert[0])
{
temp = currentOutput[id];
currentOutput[id + 1] = temp;
}
barrier(CLK_LOCAL_MEM_FENCE);
if ((float)id > positionToInsert[0])
{
temp = currentOutput[id];
}
barrier(CLK_LOCAL_MEM_FENCE);
if (id == round(positionToInsert[0]))
{
currentOutput[id] = addedValue[0];
noOfValuesAdded[0] = noOfValuesAdded[0] + 1;
}
}
barrier(CLK_LOCAL_MEM_FENCE);
}
barrier(CLK_LOCAL_MEM_FENCE);
array[gid*size + id] = currentOutput[id];
return;
}

Convert a string from UART to hex value in c

I am working on pic controllers. I have a string "040F" which is sent to the controller through UART.
I want to convert this string to a hex representation such as 0x040F. I tried a code snippet but no success.
Can anyone please help me out.
If what you mean is to convert a hex string to binary, the below code can help. It may not be an optimized one and may be other simpler solutions are available in the internet and can be even buggy. But it will give you some idea, I hope.
#include<stdio.h>
#include<string.h>
#define MAX_STR_LEN 16
int hex_char_to_bin(char ch)
{
if(ch >= '0' && ch <= '9')
{
return (ch - '0');
}
else if(ch >= 'a' && ch <= 'f')
{
return (10 + ch - 'a');
}
else if(ch >= 'A' && ch <= 'F')
{
return (10 + ch - 'A');
}
return -1;
}
int hex_str_to_bin(const char *hex_str, int *result)
{
int str_len, i;
int bin_val = 0;
str_len = strnlen(hex_str, MAX_STR_LEN);
for (i = 0; i < str_len; i++)
{
int val = hex_char_to_bin(*hex_str++);
if (val == -1)
return -1;
bin_val = (bin_val<<4) + val;
}
*result = bin_val;
return 0;
}
int main()
{
char str[] = "043f";
int hex;
if(!hex_str_to_bin(str, &hex))
printf("%x\n",hex);
else
printf("Invalid hex charecters in string\n");
return 0;
}

Resources