当我尝试将双精度数作为元素分解为数组时,为什么我会得到一个偏移量阻止我获取最后一位数字?
When I try to decompose a double number into an array as elements, why do I get an offset preventing me from getting the last digit?
我有问题。 我想从给定的数字中获取每个数字作为同一数组中的一个元素。
但是当我编译时,如果我将一次迭代的范围扩展到给定数字的大小以上,我会在调试模式下从 Visual Studio 得到一个损坏的数据异常作为异常。
我首先想到的是因为 int 类型作为 4 字节实体的最大长度只有 4 位数字,因为我过去只得到一位数字来表示大于 9999 的数字。但我注意到我的数字从迭代值开始一个太晚了...这使得无法显示最后一位数字。
如果我给给定的数字加一个零,我可以在相反的方向手动偏移,但这对我的原始数字不起作用。
但是,我找不到解决方法...这是我的代码。
在寻求帮助之前,这里有一个屏幕截图解释了用于将数字转换为数组的原理:math theory formula
我只想用数字类型解决它,因为 char 类型涉及另一种使用缓冲区管理内存的方式......我真的不知道如何处理。
有人可以帮我完成调试吗?
#include <iostream>
#include <math.h>
//method to convert user number entry to array of digits
long long numToArray(double num,double arrDigits[], const long long n) {
//instanciate variables
//array of with m elements
arrDigits[n];
double* loopValue = new double(0);
//extract the digits and store them into arrDigits array
for (long long i = 0; i < n; i++) {
long temp = 0;
for (long k = 0; k < i + 1; k++) {
//mathematical general formula
temp += arrDigits[i - k] * pow(10, k);
loopValue = new double(0);
*loopValue = floor(num / pow(10, n - i)) - temp;
arrDigits[i] = *loopValue;
}
std::cout << "digits array value at " << i << " is " << arrDigits[i] << " \n";
}
return 0;
}
//main program interacting with the user
int main()
{
std::cout << "please type an integer: ";
double num;
const long long n = sizeof(num);
double array[n]{};
std::cin >> num;
//call the method to test if all values are in the array
numToArray(num, array, n);
return 0;
}
Explaining the troubleshoot
注意:如果我从 n 扩展到 n+1,Visual Studio 会显示错误。如果我让类型为 int 或 long,则 sizeof(num) 始终为 4 ...
然后,我必须将它设置为 double 并从主作用域中提取它,这使得它 ...double...
人们要求删除指针,如果我这样做,运行 程序是不可能的。
I want from a given number to get each digit as an element in the same array.
如果想简单的把每个数放到一个数组中,只需要几行代码就可以把小数转换成字符串,去掉小数点(如果有的话),然后把字符串复制到一个缓冲区:
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <iomanip>
int main()
{
double d = 1.45624234;
std::ostringstream strm;
strm << std::setprecision(12);
// copy this to a string using the output stream
strm << d;
std::string s = strm.str();
// remove the decimal point
s.erase(std::remove(s.begin(), s.end(), '.'), s.end());
// Now copy each digit to a buffer (in this case, vector)
std::vector<int> v;
std::transform(s.begin(), s.end(), std::back_inserter(v), [&](char ch) { return ch - '0';});
// output the results
for (auto c : v )
std::cout << c;
}
输出:
145624234
标准库已经为您完成了您所做的所有工作。在这种情况下,当流式传输到缓冲区时,double
的重载 operator <<
会创建字符串。它是怎么做到的?这基本上就是您的代码试图做的事情,但显然是安全和正确的。
然后只需将每个数字字符转换为表示该数字的实际整数,这就是 std::transform
所做的。通过从每个 char 数字中减去字符 0
,将每个数字字符复制到向量中。
#include <iostream>
#include <math.h>
#include <list>
int main()
{
//Entry request of any natural integer within the range of double type
std::cout << "Please type a natural integer from 1 to 99999999\n";
double num;
std::cin >> num;
//counting the number of digits
int count = 0;
long long CountingNum = static_cast<long long>(num);
while (CountingNum != 0) {
CountingNum = CountingNum/10;
++count;
}
std::cout << "number of digits compositing your natural integer: " << count<<std::endl;
//process the value for conversion to list of digits, so you can
//access each digits by power and enhance your calculus operations
double converternum = num * 10;//removing the right offset to keep the last digit
const int containerSize = sizeof(double); //defining array constant size
int sizeRescale = containerSize - count;//set general offset to handle according to the user entry
double arrDigits[containerSize] = {};//initialize array with a sufficient size.
double* loopValue = new double(0); //define pointer variable to make to operation possible
//extract the digits and store them into arrDigits array
for (long long i = 0; i < containerSize; i++) {
long temp = 0;
for (long k = 0; k < i + 1; k++) {
//mathematical general formula adapted to the computation
temp += arrDigits[i - k] * pow(10, k);
loopValue = new double(0); //reinitialize the pointer
*loopValue = floor(converternum / pow(10, containerSize - i)) - temp; //assign the math formula to the pointer
arrDigits[i] = *loopValue;//assigne the formula for any i to the array relatively to k
}
std::cout << "digits array value at " << i << " is " << arrDigits[i] << " \n";
}
//convert array to a list
std::list<double> listDigits(std::begin(arrDigits), std::end(arrDigits));
//print the converted list
std::cout << "array converted to list: ";
for (double j : listDigits) {
std::cout << j << " ";
}
std::cout << std::endl;
//remove the zeros offset and resize the new converted list
for (int j = 0; j < sizeRescale; j++) {
listDigits.pop_front();
}
std::cout << "removed zero element to the list\n";
for (double i : listDigits) {
std::cout << i << " ";
}
std::cout << "natural integer successfully converted into list digits data\n";
return 0;
}
an example on debug mode in Visual Studio 2019
最后我把整个代码封装成了两个函数。但是我在第一次和最后一次迭代中有额外的价值...
答案基本完成,只需要解决从main内部移动到它拥有的函数的偏移量。我终于从两个新函数中添加了一个新的数组变量,它具有我想要的确切大小,所以我们得到了可以在很远的地方操作的数组。
#include <iostream>
#include <math.h>
#include <list>
int CountNumberDigits(int num) {
int count = 0;
long long CountingNum = static_cast<long long>(num);
while (CountingNum != 0) {
CountingNum = CountingNum / 10;
++count;
}
return count;
}
double* NumToArray(double num) {
double converternum = num * 10;//removing the right offset to keep the last digit
const int containerSize = sizeof(double); //defining array constant size
int sizeRescale = containerSize - CountNumberDigits(num);//set general offset to handle according to the user entry
double arrDigits[containerSize] = {};//initialize array with a sufficient size.
double* loopValue = new double(0); //define pointer variable to make to operation possible
//extract the digits and store them into arrDigits array
for (long long i = 0; i < containerSize; i++) {
long temp = 0;
for (long k = 0; k < i + 1; k++) {
//mathematical general formula adapted to the computation
temp += arrDigits[i - k] * pow(10, k);
loopValue = new double(0); //reinitialize the pointer
*loopValue = floor(converternum / pow(10, containerSize - i)) - temp; //assign the math formula to the pointer
arrDigits[i] = *loopValue;//assigne the formula for any i to the array relatively to k
}
}
//convert array to a list
std::list<double> listDigits(std::begin(arrDigits), std::end(arrDigits));
for (double j : listDigits) {
std::cout << j << " ";
}
//remove the zeros offset and resize the new converted list
for (int j = 0; j < sizeRescale; j++) {
listDigits.pop_front();
}
//convert list to array
double* arrOutput = new double[listDigits.size()]{};
std::copy(listDigits.begin(), listDigits.end(), arrOutput);
double* ptrResult = arrOutput;
return ptrResult;
}
int main()
{
//Entry request of any natural integer within the range of double type
std::cout << "Please type a natural integer from 1 to 99999999\n";
double num;
std::cin >> num;
int count = CountNumberDigits(num);
std::cout << "number of digits compositing your natural integer: " << count << std::endl;
double* ptrOutput = NumToArray(num);
//reduce the array to the num size
double* shrinkArray = new double[CountNumberDigits(num)];
for (int i = 0; i < CountNumberDigits(num); i++) {
*(shrinkArray+i) = ptrOutput[i];
std::cout << *(shrinkArray+i) << " ";
}
我有问题。 我想从给定的数字中获取每个数字作为同一数组中的一个元素。
但是当我编译时,如果我将一次迭代的范围扩展到给定数字的大小以上,我会在调试模式下从 Visual Studio 得到一个损坏的数据异常作为异常。
我首先想到的是因为 int 类型作为 4 字节实体的最大长度只有 4 位数字,因为我过去只得到一位数字来表示大于 9999 的数字。但我注意到我的数字从迭代值开始一个太晚了...这使得无法显示最后一位数字。
如果我给给定的数字加一个零,我可以在相反的方向手动偏移,但这对我的原始数字不起作用。
但是,我找不到解决方法...这是我的代码。 在寻求帮助之前,这里有一个屏幕截图解释了用于将数字转换为数组的原理:math theory formula 我只想用数字类型解决它,因为 char 类型涉及另一种使用缓冲区管理内存的方式......我真的不知道如何处理。
有人可以帮我完成调试吗?
#include <iostream>
#include <math.h>
//method to convert user number entry to array of digits
long long numToArray(double num,double arrDigits[], const long long n) {
//instanciate variables
//array of with m elements
arrDigits[n];
double* loopValue = new double(0);
//extract the digits and store them into arrDigits array
for (long long i = 0; i < n; i++) {
long temp = 0;
for (long k = 0; k < i + 1; k++) {
//mathematical general formula
temp += arrDigits[i - k] * pow(10, k);
loopValue = new double(0);
*loopValue = floor(num / pow(10, n - i)) - temp;
arrDigits[i] = *loopValue;
}
std::cout << "digits array value at " << i << " is " << arrDigits[i] << " \n";
}
return 0;
}
//main program interacting with the user
int main()
{
std::cout << "please type an integer: ";
double num;
const long long n = sizeof(num);
double array[n]{};
std::cin >> num;
//call the method to test if all values are in the array
numToArray(num, array, n);
return 0;
}
Explaining the troubleshoot
注意:如果我从 n 扩展到 n+1,Visual Studio 会显示错误。如果我让类型为 int 或 long,则 sizeof(num) 始终为 4 ... 然后,我必须将它设置为 double 并从主作用域中提取它,这使得它 ...double... 人们要求删除指针,如果我这样做,运行 程序是不可能的。
I want from a given number to get each digit as an element in the same array.
如果想简单的把每个数放到一个数组中,只需要几行代码就可以把小数转换成字符串,去掉小数点(如果有的话),然后把字符串复制到一个缓冲区:
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <iomanip>
int main()
{
double d = 1.45624234;
std::ostringstream strm;
strm << std::setprecision(12);
// copy this to a string using the output stream
strm << d;
std::string s = strm.str();
// remove the decimal point
s.erase(std::remove(s.begin(), s.end(), '.'), s.end());
// Now copy each digit to a buffer (in this case, vector)
std::vector<int> v;
std::transform(s.begin(), s.end(), std::back_inserter(v), [&](char ch) { return ch - '0';});
// output the results
for (auto c : v )
std::cout << c;
}
输出:
145624234
标准库已经为您完成了您所做的所有工作。在这种情况下,当流式传输到缓冲区时,double
的重载 operator <<
会创建字符串。它是怎么做到的?这基本上就是您的代码试图做的事情,但显然是安全和正确的。
然后只需将每个数字字符转换为表示该数字的实际整数,这就是 std::transform
所做的。通过从每个 char 数字中减去字符 0
,将每个数字字符复制到向量中。
#include <iostream>
#include <math.h>
#include <list>
int main()
{
//Entry request of any natural integer within the range of double type
std::cout << "Please type a natural integer from 1 to 99999999\n";
double num;
std::cin >> num;
//counting the number of digits
int count = 0;
long long CountingNum = static_cast<long long>(num);
while (CountingNum != 0) {
CountingNum = CountingNum/10;
++count;
}
std::cout << "number of digits compositing your natural integer: " << count<<std::endl;
//process the value for conversion to list of digits, so you can
//access each digits by power and enhance your calculus operations
double converternum = num * 10;//removing the right offset to keep the last digit
const int containerSize = sizeof(double); //defining array constant size
int sizeRescale = containerSize - count;//set general offset to handle according to the user entry
double arrDigits[containerSize] = {};//initialize array with a sufficient size.
double* loopValue = new double(0); //define pointer variable to make to operation possible
//extract the digits and store them into arrDigits array
for (long long i = 0; i < containerSize; i++) {
long temp = 0;
for (long k = 0; k < i + 1; k++) {
//mathematical general formula adapted to the computation
temp += arrDigits[i - k] * pow(10, k);
loopValue = new double(0); //reinitialize the pointer
*loopValue = floor(converternum / pow(10, containerSize - i)) - temp; //assign the math formula to the pointer
arrDigits[i] = *loopValue;//assigne the formula for any i to the array relatively to k
}
std::cout << "digits array value at " << i << " is " << arrDigits[i] << " \n";
}
//convert array to a list
std::list<double> listDigits(std::begin(arrDigits), std::end(arrDigits));
//print the converted list
std::cout << "array converted to list: ";
for (double j : listDigits) {
std::cout << j << " ";
}
std::cout << std::endl;
//remove the zeros offset and resize the new converted list
for (int j = 0; j < sizeRescale; j++) {
listDigits.pop_front();
}
std::cout << "removed zero element to the list\n";
for (double i : listDigits) {
std::cout << i << " ";
}
std::cout << "natural integer successfully converted into list digits data\n";
return 0;
}
an example on debug mode in Visual Studio 2019
最后我把整个代码封装成了两个函数。但是我在第一次和最后一次迭代中有额外的价值...
答案基本完成,只需要解决从main内部移动到它拥有的函数的偏移量。我终于从两个新函数中添加了一个新的数组变量,它具有我想要的确切大小,所以我们得到了可以在很远的地方操作的数组。
#include <iostream>
#include <math.h>
#include <list>
int CountNumberDigits(int num) {
int count = 0;
long long CountingNum = static_cast<long long>(num);
while (CountingNum != 0) {
CountingNum = CountingNum / 10;
++count;
}
return count;
}
double* NumToArray(double num) {
double converternum = num * 10;//removing the right offset to keep the last digit
const int containerSize = sizeof(double); //defining array constant size
int sizeRescale = containerSize - CountNumberDigits(num);//set general offset to handle according to the user entry
double arrDigits[containerSize] = {};//initialize array with a sufficient size.
double* loopValue = new double(0); //define pointer variable to make to operation possible
//extract the digits and store them into arrDigits array
for (long long i = 0; i < containerSize; i++) {
long temp = 0;
for (long k = 0; k < i + 1; k++) {
//mathematical general formula adapted to the computation
temp += arrDigits[i - k] * pow(10, k);
loopValue = new double(0); //reinitialize the pointer
*loopValue = floor(converternum / pow(10, containerSize - i)) - temp; //assign the math formula to the pointer
arrDigits[i] = *loopValue;//assigne the formula for any i to the array relatively to k
}
}
//convert array to a list
std::list<double> listDigits(std::begin(arrDigits), std::end(arrDigits));
for (double j : listDigits) {
std::cout << j << " ";
}
//remove the zeros offset and resize the new converted list
for (int j = 0; j < sizeRescale; j++) {
listDigits.pop_front();
}
//convert list to array
double* arrOutput = new double[listDigits.size()]{};
std::copy(listDigits.begin(), listDigits.end(), arrOutput);
double* ptrResult = arrOutput;
return ptrResult;
}
int main()
{
//Entry request of any natural integer within the range of double type
std::cout << "Please type a natural integer from 1 to 99999999\n";
double num;
std::cin >> num;
int count = CountNumberDigits(num);
std::cout << "number of digits compositing your natural integer: " << count << std::endl;
double* ptrOutput = NumToArray(num);
//reduce the array to the num size
double* shrinkArray = new double[CountNumberDigits(num)];
for (int i = 0; i < CountNumberDigits(num); i++) {
*(shrinkArray+i) = ptrOutput[i];
std::cout << *(shrinkArray+i) << " ";
}