Why this error happens while showing array out in C? - arrays

What I'm making is input a number that type is 'unsigned long long' and then make it to binary form and show it by 16 figures.
Here's my code and result.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
char D_PAN_ID[16];
char D_ADDRESS[16];
char S_PAN_ID[16];
char S_ADDRESS[16];
int main()
{
int bit1, bit2, bit3, bit4, k1, k2, k3, k4;
unsigned long long dec = 5;
/*
printf("8바이트 정수를 이진수로 변환\n");
scanf("%llu", &dec);
*/
printf("%llu 를(을) 이진수로 변환하면:\n", dec);
for (bit1 = 63; bit1 >= 48; bit1--)
{
k1 = dec >> bit1;
if (k1 & 1) {
D_PAN_ID[63 - bit1] = '1';
printf(&D_PAN_ID[63 - bit1]);
}
else {
D_PAN_ID[63 - bit1] = '0';
printf(&D_PAN_ID[63 - bit1]);
}
}
printf("\n\n");
for (bit2 = 47; bit2 >= 32; bit2--)
{
k2 = dec >> bit2;
if (k2 & 1) {
D_ADDRESS[47 - bit2] = '1';
printf(&D_ADDRESS[47 - bit2]);
}
else {
D_ADDRESS[47 - bit2] = '0';
printf(&D_ADDRESS[47 - bit2]);
}
}
printf("\n\n");
for (bit3 = 31; bit3 >= 16; bit3--)
{
k3 = dec >> bit3;
if (k3 & 1) {
S_PAN_ID[31 - bit3] = '1';
printf(&S_PAN_ID[31 - bit3]);
}
else {
S_PAN_ID[31 - bit3] = '0';
printf(&S_PAN_ID[31 - bit3]);
}
}
printf("\n\n");
for (bit4 = 15; bit4 >= 0; bit4--)
{
k4 = dec >> bit4;
if (k4 & 1) {
S_ADDRESS[15 - bit4] = '1';
printf(&S_ADDRESS[15 - bit4]);
}
else {
S_ADDRESS[15 - bit4] = '0';
printf(&S_ADDRESS[15 - bit4]);
}
}
return 0;
}
And what I got is this. I think it is adding upper result at back since printing second result. Like this:
result1
result2 + result1
result3 + result1 + result2
result4 + result1 + result2 + result3
How do I fix it to show like
000000000000
000000000000
000000000000
000000000101

Related

C++ writing TDengine database with error occasionally

When I use below code to insert into TDengine database ,sometimes it will lose connection.
you can compile it and run to reproduce issue ,anyone could help on this ?
I use the async taos_query_a API to test the response time .:
//
// Created by jia.wen on 8/15/22.
//
//#include <fmt/format.h>
#include <chrono>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <unistd.h>
#include <vector>
#include <taos.h>
static unsigned long long get_nanosecs_since_epoch()
{
using namespace std::chrono;
return static_cast<unsigned long long>(duration_cast<nanoseconds>(
system_clock::now().time_since_epoch()).count());
}
static std::string format_nanosecs_since_epoch(unsigned long long nanosecs_since_epoch)
{
std::time_t secs_since_epoch(nanosecs_since_epoch / 1000000000);
std::tm secs_since_epoch_tm;
localtime_r(&secs_since_epoch, &secs_since_epoch_tm);
unsigned long long remaining_nanosecs = nanosecs_since_epoch % 1000000000;
char buffer[30];
int year = secs_since_epoch_tm.tm_year + 1900;
buffer[0] = (year / 1000) + '0';
buffer[1] = (year % 1000) / 100 + '0';
buffer[2] = (year % 100) / 10 + '0';
buffer[3] = (year % 10) + '0';
buffer[4] = '-';
int month = secs_since_epoch_tm.tm_mon + 1;
buffer[5] = (month / 10) + '0';
buffer[6] = (month % 10) + '0';
buffer[7] = '-';
buffer[8] = (secs_since_epoch_tm.tm_mday / 10) + '0';
buffer[9] = (secs_since_epoch_tm.tm_mday % 10) + '0';
buffer[10] = ' ';
buffer[11] = (secs_since_epoch_tm.tm_hour / 10) + '0';
buffer[12] = (secs_since_epoch_tm.tm_hour % 10) + '0';
buffer[13] = ':';
buffer[14] = (secs_since_epoch_tm.tm_min / 10) + '0';
buffer[15] = (secs_since_epoch_tm.tm_min % 10) + '0';
buffer[16] = ':';
buffer[17] = (secs_since_epoch_tm.tm_sec / 10) + '0';
buffer[18] = (secs_since_epoch_tm.tm_sec % 10) + '0';
buffer[19] = '.';
buffer[20] = (remaining_nanosecs / 100000000) + '0';
buffer[21] = (remaining_nanosecs % 100000000) / 10000000 + '0';
buffer[22] = (remaining_nanosecs % 10000000) / 1000000 + '0';
buffer[23] = (remaining_nanosecs % 1000000) / 100000 + '0';
buffer[24] = (remaining_nanosecs % 100000) / 10000 + '0';
buffer[25] = (remaining_nanosecs % 10000) / 1000 + '0';
buffer[26] = (remaining_nanosecs % 1000) / 100 + '0';
buffer[27] = (remaining_nanosecs % 100) / 10 + '0';
buffer[28] = (remaining_nanosecs % 10) + '0';
buffer[29] = 0;
return std::string(buffer);
}
void taos_insert_call_back(void* param, TAOS_RES* tres, int code)
{
unsigned long long* insert_time = (unsigned long long *)param;
struct timeval systemTime;
char sql[128];
if (code < 0)
{
printf("Insert failed. code:%d, cause:%s\n", code, taos_errstr(tres));
}
else if (code == 0)
{
// printf("Not inserted.\n");
}
else
{
printf("Succeed.\n");
}
taos_free_result(tres);
}
int main()
{
const char *host = "localhost:6030";
const char *user = "root";
const char *passwd = "taosdata";
const char *db = "test_lts";
uint16_t port = 0; // 0 means use the default port
TAOS *taos = taos_connect(host, user, passwd, db, port);
if (taos == NULL)
{
int errno_n = taos_errno(NULL);
auto msg = taos_errstr(NULL);
printf("%d, %s\n", errno, msg);
}
else
{
printf("connected\n");
std::string ins_sql;
std::vector<int> test_cycles_;
TAOS_RES* exec_result = NULL;
int cycles = 60;
int insert_times = 2000;
for (auto i = 0; i < cycles; ++i)
{
for (auto j = 0; j < insert_times; ++j)
{
auto local_time = format_nanosecs_since_epoch(get_nanosecs_since_epoch());
ins_sql = "INSERT INTO tick_jw VALUES ('" + local_time + "'," + std::to_string(i + 1) + ", 20221018, " + std::to_string(j)
+ ", 'test', 1.2, 200, 1000, 0, 0, 0, "
"1.15, 1.14, 1.13, 1.12, 1.11, 5, 4, 3, 2, 1, 1.16, 1.17, 1.18, 1.19, 1.20, 5, 4, 3, 2, 1)";
taos_query_a(taos, ins_sql.c_str(), taos_insert_call_back, (void *)(0));
// usleep(60);
}
std::cout << "cycles = " << i + 1 << " finished." << std::endl;
// sleep(1);
}
std::cout << "insert_times = " << insert_times << " test async finished." << std::endl;
sleep(60);
taos_close(taos);
}
taos_cleanup();
}
the core part is just :taos_query_a(taos, ins_sql.c_str(), taos_insert_call_back, (void *)(0));

Adding decimal numbers as strings in C

So I understand how to perform calculations on integers represented in strings and then printing the result in a string. But I'm lost on how to do the same thing with a decimal in the number represented in a string.
Here's how I did it with integers. This part of the code is adding together two integers:
int answer = 0;
char str1[100];
int count = 0;
int total = 0;
int k = 0;
int diff = 0;
if (ele == ele2) {
for (k = strlen(op1) - 1; k > -1; k--) {
if ((strspn(operand, "+") == strlen(operand))) {
answer = (op1[k] - '0') + (op2[k] - '0');
} else if ((strspn(operand, "-") == strlen(operand))) {
answer = (op1[k] - '0') - (op2[k] - '0');
}
total += (pow(10, count) * answer);
count++;
}
sprintf(str1, "%d", total);
printf("Answer: %s ", str1);
}
Output
// 12 + 14
Answer: 26 // Answer given as a string
Example
12.2 + 14.5 // Three strings
Answer: 16.7 // Answer as string
Current Attempt:
for (k = strlen(argv[1]) - 1; k > -1; k--) {
if (argv[1][k] == '.') {
dec = k;
} else {
answer = (argv[1][k] - '0') + (argv[3][k] - '0');
total += (pow(10, count) * answer);
count++;
}
}
// needs to be converted to a long?
// ele is the length of the operand
total = total / pow(10, ele - dec);
sprintf(str1, "%d", total);
printf("Answer: %s ", str1);
Sharing a simple algo to begin with (and assuming your adding integer funciton works fine).
A decimal number is basically two integers separated by ".".
Identify the position of "." and grab the two sides of the integer as integerPart, decimalPart
One caveat on getting the decimalPart is that the length of all the decimalParts should be same, if not, add "0"s in the suffix.
Add the integerPart, add the decimalPart and handle the carryForwards in the decimalPart.
So,
12.2 + 14.95
= (12 + 14) (20 + 95)
= 26 115
= 26+1 15
= 27.15
This is a quick and dirty implementation: no parameter check, no deep test only an idea of how you should process.
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int total_digits;;
int decimal_points;
int *number;
} NUMBER, *DECIMALNUMBER;
DECIMALNUMBER initilize(char *str)
{
DECIMALNUMBER result = calloc(1, sizeof(NUMBER));
int in_decimal = 0;
char *s;
int i;
for (s = str; *s; s++)
{
if (isdigit(*s))
{
result->total_digits++;
if (in_decimal)
{
result -> decimal_points++;
}
}
else if (*s == '.')
{
in_decimal = 1;
}
else
{
return NULL;
}
}
result->number = calloc(result->decimal_points, sizeof(int));
i=0;
for (s = str; *s; s++)
{
if (isdigit(*s))
{
result->number[i++] = (int)(*s - '0');
}
}
// printf("result->total_digits is %d\n",result->total_digits);
// printf("result->decimal_points is %d\n",result->decimal_points);
// printf("result is %d\n",result->number[--i]);
// printf("result is %d\n",result->number[--i]);
// printf("result is %d\n",result->number[--i]);
return result;
}
void print_number(DECIMALNUMBER p)
{
int i;
for (i=0; i<p->total_digits; i++)
{
if (i==p->total_digits - p->decimal_points) {
printf(".");
}
printf("%d", p->number[i]);
}
printf("\n");
}
DECIMALNUMBER sum(DECIMALNUMBER a, DECIMALNUMBER b)
{
int max_decimals = a->decimal_points>b->decimal_points ? a->decimal_points : b->decimal_points;
int max_digits_count = a->total_digits>b->total_digits ? a->total_digits : b->total_digits;
DECIMALNUMBER result = calloc(1, sizeof(NUMBER));
result->total_digits = max_digits_count;
result->decimal_points = max_decimals;
result->number = calloc(max_digits_count, sizeof(int));
int i1 = a->total_digits-1;
int i2 = b->total_digits-1;
int i3 = result->total_digits-1;
int remainder = 0;
int summed;
while (i1 >= 0 || i2 >=0)
{
int aa = i1 < 0 ? 0 : a->number[i1];
int bb = i2 < 0 ? 0 : b->number[i2];
summed = aa + bb + remainder;
result->number[i3] = summed % 10;
remainder = summed / 10;
i1--;
i2--;
i3--;
}
return result;
}
int main()
{
DECIMALNUMBER a = initilize("12.2");
DECIMALNUMBER b = initilize("16.7");
print_number(a);
print_number(b);
DECIMALNUMBER c = sum (a,b);
print_number(c);
return 0;
}

Fixed point square root function wrong results for big numbers

Hello friends and enemies
I have this square root function from a library called libfixmath which works great, however from 32767.0f and above it starts returning wrong and negative results. The numbers I need square root of are rather big, up to 999999.0f. Any of you know what I could do to fix the problem?
#include <iostream>
float into_float(const int value) {
return ((float)value / 65536.0f);
}
int from_float(const float value) {
return (int)(value * 65536.0f);
}
int fp_sqrt(int value) {
unsigned char neg = (value < 0);
unsigned int num = (neg ? -value : value);
unsigned int result = 0;
unsigned int bit;
unsigned char n;
if (num & 0xFFF00000) {
bit = (unsigned int)1 << 30;
} else {
bit = (unsigned int)1 << 18;
}
while (bit > num) bit >>= 2;
for (n = 0; n < 2; n++) {
while (bit) {
if (num >= result + bit) {
num -= result + bit;
result = (result >> 1) + bit;
} else {
result = (result >> 1);
}
bit >>= 2;
}
if (n == 0) {
if (num > 65535) {
num -= result;
num = (num << 16) - 0x8000;
result = (result << 16) + 0x8000;
} else {
num <<= 16;
result <<= 16;
}
bit = 1 << 14;
}
}
if (num > result) {
result++;
}
return (neg ? -result : result);
}
void main() {
float flt_value = 32767.0f;
int int_value = from_float(flt_value);
float flt_root = sqrt(flt_value);
int int_root = fp_sqrt(int_value);
float flt_root2 = into_float(int_root);
printf("sqrt: %f fp_sqrt: %f", flt_root, flt_root2);
getchar();
}
Thank you leppie, I changed some stuff around and it works with big numbers now, I am not sure if what I did is totally right though but here it is:
#include <iostream>
float into_float(const int value) {
return ((float)value / 65536.0f);
}
long long from_float(const float value) {
return (long long)(value * 65536.0f);
}
long long fp_sqrt(long long value) {
unsigned char neg = (value < 0);
long long num = (neg ? -value : value);
long long result = 0;
long long bit;
unsigned char n;
if (num & 0xFFF00000) {
bit = (long long)1 << 60;
} else {
bit = (long long)1 << 36;
}
while (bit > num) bit >>= 2;
for (n = 0; n < 2; n++) {
while (bit) {
if (num >= result + bit) {
num -= result + bit;
result = (result >> 1) + bit;
} else {
result = (result >> 1);
}
bit >>= 2;
}
if (n == 0) {
if (num > 65535) {
num -= result;
num = (num << 16) - 0x8000;
result = (result << 16) + 0x8000;
} else {
num <<= 16;
result <<= 16;
}
bit = 1 << 14;
}
}
if (num > result) {
result++;
}
return (neg ? -result : result);
}
void main() {
float flt_value = 11932767.0f;
long long ll_value = from_float(flt_value);
float flt_root = sqrt(flt_value);
int int_root = (int)fp_sqrt(ll_value);
float flt_root2 = into_float(int_root);
printf("sqrt: %f fp_sqrt: %f", flt_root, flt_root2);
getchar();
}

Using arrays for BCD conversion in C

I'm working on a project where I need to convert some long variables into BCD.
I already have some code that works but I feel that it can be improved...
void main(void){
unsigned long input = 0;
unsigned long convert = 0;
float convert2 = 0;
char buffer[200];
unsigned char Ones, Tens, Hundreds, Thousands, TenThousands, HundredThousands;
printf("Input: ");
scanf("%d", &input);
convert = input*12;
convert2 = input * 0.0001224896;
BCD(convert, &Ones, &Tens, &Hundreds, &Thousands, &TenThousands, &HundredThousands);
sprintf(buffer, "%d%d%dKG", HundredThousands, TenThousands, Thousands);
printf("\n\nInputted: %d", input);
printf("\nADC Conversion: %d", convert);
printf("\nBCD Conversion: %s", buffer);
printf("\nFloat Conversion: %f", convert2);
getchar();
getchar();
}
void BCD (unsigned long Pass, unsigned char *Ones, unsigned char *Tens, unsigned char *Hundreds, unsigned char *Thousands, unsigned char *TenThousands, unsigned char *HundredThousands){
unsigned char temp1, temp2, temp3, temp4, temp5, temp6;
unsigned int count = 0;
*Ones = 0;
*Tens = 0;
*Hundreds = 0;
*Thousands = 0;
*TenThousands = 0;
*HundredThousands = 0;
temp1 = 0;
temp2 = 0;
temp3 = 0;
temp4 = 0;
temp5 = 0;
temp6 = 0;
for(count = 0; count <= 31; count++){
if (*Ones >= 5){
*Ones = (*Ones + 3)&0x0F;
}
if (*Tens >= 5){
*Tens = (*Tens + 3)&0x0F;
}
if (*Hundreds >= 5){
*Hundreds = (*Hundreds + 3)&0x0F;
}
if (*Thousands >= 5){
*Thousands = (*Thousands + 3)&0x0F;
}
if (*TenThousands >= 5){
*TenThousands = (*TenThousands + 3)&0x0F;
}
if (*HundredThousands >= 5){
*HundredThousands = (*HundredThousands + 3)&0x0F;
}
temp1 = (Pass & 2147483648) >> 31;
temp2 = (*Ones & 8) >> 3;
temp3 = (*Tens & 8) >> 3;
temp4 = (*Hundreds & 8) >> 3;
temp5 = (*Thousands & 8) >> 3;
temp6 = (*TenThousands & 8) >> 3;
Pass = Pass << 1;
*Ones = ((*Ones << 1) + temp1) & 15;
*Tens = ((*Tens << 1) + temp2) & 15;
*Hundreds = ((*Hundreds << 1) + temp3) & 15;
*Thousands = ((*Thousands << 1) + temp4) & 15;
*TenThousands = ((*TenThousands << 1) + temp5) & 15;
*HundredThousands = ((*HundredThousands << 1) + temp6) & 15;
printf("\n\nLoop: %d\nOnes: %d\n", count, *Ones);
printf("Tens: %d\n", *Tens);
printf("Hundreds: %d\n", *Hundreds);
printf("Thousands: %d\n", *Thousands);
printf("TenThousands: %d\n", *TenThousands);
printf("HundredThousands: %d\n",*HundredThousands);
}
}
The problem I have with this is that it seems messy and inefficient. I was think that instead of using multiple variable for each BCD unit (Ones, Tens, etc), I could use an arrays to carry out the same process. I have implemented this in code but I'm running into a few problems. The code only seems to display "Ones" equivalent element. I've stepped through the code as well and found that the other elements are not being populated during the conversion process. Any guidance on what is going on?
Array implementation:
void main(void){
unsigned long input = 0;
unsigned long convert = 0;
char buffer[200];
unsigned char BCD_Units[6];
unsigned char temp[6];
unsigned int count = 0;
unsigned int count1 = 0;
unsigned char buff_store = 0;
unsigned char buff_store2 = 0;
printf("Input: ");
scanf("%d", &input);
convert = input;
memset(temp, 0, sizeof(temp));
memset(BCD_Units, 0, sizeof(BCD_Units));
for(count = 0; count <= 31; count++){
for (count1 = 0; count1 < 6; count1++){
if (BCD_Units[count1] >= 5){
buff_store = BCD_Units[count1];
buff_store = ((buff_store + 3) & 15);
BCD_Units[count1] = buff_store;
}
}
temp[0] = (convert & 2147483648) >> 31;
for (count1 = 0; count1 < 5; count1++){
buff_store = BCD_Units[count1];
temp[(count+1)] = (buff_store & 8) >> 3;
}
convert = convert << 1;
for(count1 = 0; count1 < 6; count1++){
buff_store = BCD_Units[count1];
buff_store2 = temp[count1];
buff_store = ((buff_store << 1) + buff_store2) & 15;
BCD_Units[count1] = buff_store;
temp[count1] = buff_store2;
}
printf("\n\nLoop: %d\nOnes: %d\n", count, BCD_Units[0]);
printf("Tens: %d\n", BCD_Units[1]);
printf("Hundreds: %d\n", BCD_Units[2]);
printf("Thousands: %d\n", BCD_Units[3]);
printf("TenThousands: %d\n", BCD_Units[4]);
printf("HundredThousands: %d\n", BCD_Units[5]);
}
sprintf(buffer, "%d%d%dKG", BCD_Units[5], BCD_Units[4], BCD_Units[3]);
printf("\n\nInputted: %d", input);
printf("\nBCD Conversion: %s", buffer);
getchar();
getchar();
}
PS. I'm just playing around, at the moment, with ideas. I plan to compartmentalise the code into functions at a later date.
this code seems enormously complicated. YOu just need to do the following
make a buffer
loop till n = 0
get n % 10 (get digit)
or digit into left or right nibble of curretn buffer byte (need a toggle for left or right)
increment buffer pointer if filled left nibble
n = n / 10
try this Convert integer from (pure) binary to BCD

Send a variable to a function and modify this variable in C

I have the following vars:
char seed[NBITS + 1], x0[NBITS + 1], y0[NBITS + 1], z0[NBITS + 1], dT0[NBITS + 1];
And i want to change it values on this function:
void lfsr(char *bin, char *output)
{
//bits significativos para fazer o xor NBITS -> NBITS,126,101,99;
int bits[4];
int bit;
if(bin[0] == '0')
bits[0] = 0;
else if(bin[0] == '1')
bits[0] = 1;
if(bin[2] == '0')
bits[1] = 0;
else if(bin[2] == '1')
bits[1] = 1;
if(bin[21] == '0')
bits[2] = 0;
else if(bin[21] == '1')
bits[2] = 1;
if(bin[19] == '0')
bits[3] = 0;
else if(bin[19] == '1')
bits[3] = 1;
bit = bits[0] ^ bits[1] ^ bits[2] ^ bits[3] ^ 1;
//reconstruir o vector de char depois do lfsr
for(int i = 127; i >= 1; i--)
{
bin[i] = bin[i - 1];
}
bin[0] = (char)(48 + bit);
output = bin;
}
The way that I put the value in y0 from x is, for example, calling the lfsr functions like this:
lfsr(x0, y0);
What am I doing wrong?
I have to do 3 Fibonacci Linear Feedback Shift Register starting from x0.
x0 = 10101010101010
y0 = lfsr(101010101010)
z0 = lfsr(y0)
dT0 = lfsr(z0);
The results are good, but when I do the above code the value of x0 will be the same as dT0 if i use pointers.
Can anyone help me?
Thanks. Cumps!
Consider the following:
The numbers correspond to the taps. The bits are actually 15..0, left to right. The following is my implementation of the Fibonacci Linear Feedback Shift Register:
#include <stdio.h>
uint16_t fibLfsr(const uint16_t num)
{
uint16_t tempNum;
tempNum = (num) ^ (num >> 2) ^ (num >> 3) ^ (num >> 5);
tempNum = (tempNum & 0x1) << 15;
tempNum = (tempNum | (num >> 1));
return tempNum;
}
int main(void)
{
uint16_t testNum = 0xACE1;
printf("%#X\n", testNum);
testNum = fibLfsr(testNum);
printf("%#X\n", testNum);
return 0;
}
I'm not quite sure why you're using strings and converting them to binary. If this is necessary, you'll need some of the standard library APIs in stdlib and string to convert the string to an uint16_t before calling fibLfsr() and back to a string afterwards.

Resources