Linux GNU Octave,将数字四舍五入到单位精度
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11386033/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
GNU Octave, round a number to units precision
提问by Eric Leschinski
In GNU Octave version 3.4.3 I want to round a matrix to 2 units precision on the contents of a matrix like this.
在 GNU Octave 3.4.3 版中,我想将矩阵四舍五入到像这样的矩阵内容的 2 个单位精度。
mymatrix=[1.1234567, 2.12345; 3.1234567891, 4.1234];
disp(mymatrix);
This prints:
这打印:
1.1235 2.1235
3.1235 4.1234
As you can see, the disp forces the precision to '5', I want the units precision to be 2. How do I do this?
如您所见,显示强制精度为“5”,我希望单位精度为 2。我该怎么做?
采纳答案by Eric Leschinski
How to round off elements in a matrix in Octave:
如何在 Octave 中舍入矩阵中的元素:
There are many different ways to round a matrix and round a number in octave.
有许多不同的方法来舍入矩阵和以八度为单位舍入数字。
Option 1, use of sprintf format feature
选项1,使用sprintf格式功能
mymatrix=[100.1234567, 2.12345; 3.1234567891, 4.1234];
rows = rows(mymatrix);
cols = columns(mymatrix);
for i = 1:rows
for j = 1:cols
sprintf("%5.2f", mymatrix(j,i))
endfor
endfor
Output, note the "%5.2f" token. The 'f' means expect a float, the 5 means occupy 5 spaces. The 2 means 2 units precision after the decimal point.
输出,注意“%5.2f”标记。'f' 表示期望一个浮点数,5 表示占用 5 个空格。2 表示小数点后 2 个单位的精度。
ans = 100.12
ans = 3.12
ans = 2.12
ans = 4.12
Option 2, round to significant digits using eval and mat2str
选项 2,使用 eval 和 mat2str 舍入到有效数字
mymatrix2=[100.1234567, 2.12345; 3.1234567891, 4.1234];
j = mat2str(mymatrix2, 3);
mymatrix2=eval(j)
Output, matrix rounded to 3 significant digits, notice 100.123 rounded to 100 while the 2.12345 was rounded to 2.12
输出,矩阵四舍五入为 3位有效数字,注意 100.123 四舍五入为 100 而 2.12345 四舍五入为 2.12
mymatrix2 =
100.0000 2.1200
3.1200 4.1200
Option 3, use the round function
选项3,使用round函数
The round function does not have a precision parameter in Octave. However you can hack around it by multiplying each item in the matrix by 100, rounding it to the nearest int, then dividing each item by 100:
圆函数在 Octave 中没有精度参数。但是,您可以通过将矩阵中的每个项目乘以 100,将其四舍五入到最接近的整数,然后将每个项目除以 100 来绕过它:
mymatrix=[100.1234567, 2.12345; 3.1234567891, 4.1234];
round(mymatrix .* 100) ./ 100
Output, round occurs correctly:
输出,回合正确发生:
ans =
100.1200 2.1200
3.1200 4.1200
Option 4, specify a output_precision(num)
选项 4,指定一个 output_precision(num)
You noticed that option 3 above kept the trailing zeros, which may be undesirable, so you can tell them to go away by setting output_precision:
您注意到上面的选项 3 保留了尾随零,这可能是不可取的,因此您可以通过设置 output_precision 告诉它们消失:
mymatrix=[100.1234567, 2.12345; 3.1234567891, 4.1234];
disp(mymatrix);
output_precision(3)
disp(mymatrix)
Output:
输出:
100.1235 2.1235
3.1235 4.1234
100.123 2.123
3.123 4.123
Octave can have some really odd behavior when trying to do rounding, remember, that octave tries hard to uniformly apply rounding to all items in a matrix. So if you have multiple columns with wildly different values, octave may look at one partcularly tiny value and think: "Hey, I should convert that to exponential: 0.0001 to 1.0e-04, and thus, the same thing is applied to the entire matrix.
Octave 在尝试进行舍入时可能会出现一些非常奇怪的行为,请记住,octave 会努力将舍入均匀地应用于矩阵中的所有项目。因此,如果您有多个具有截然不同值的列,octave 可能会查看一个特别小的值并认为:“嘿,我应该将其转换为指数:0.0001 到 1.0e-04,因此,同样的事情适用于整个矩阵。
回答by Eric Leschinski
I've found the following GNU Octave function tremendously useful. This lets you specify a custom rounding for each individual column of a MxN matrix.
我发现以下 GNU Octave 函数非常有用。这使您可以为 MxN 矩阵的每一列指定自定义舍入。
Put this function in a file called display_rounded_matrix.m
将此函数放在名为 display_rounded_matrix.m 的文件中
function display_rounded_matrix(matrix, precision, outputFile)
%precision can be a single number, applied to all, or a
%matrix of values to be applied to the columns.
space_between_columns = "";
format_part = "%10.";
precision_format = cell(columns(precision), 1);
for i = 1:columns(precision),
precision_format{i,1} = strcat(format_part, num2str(precision(1,i)), "f");
end
if (nargin == 3 && outputFile != 0)
if (rows(precision) == 1 && columns(precision) == 1)
rows = rows(matrix);
cols = columns(matrix);
format = strcat(format_part, num2str(precision), "f");
for i = 1:rows
for j = 1:cols
fprintf(outputFile, sprintf(format, matrix(i,j)));
if (j ~= cols)
fprintf(outputFile, space_between_columns);
end
end
if i ~= rows
fprintf(outputFile, "\n");
end
end
fprintf(outputFile, "\n");
elseif (rows(precision) == 1 && columns(precision) == columns(matrix))
%here we have to custom make the rounding
rows = rows(matrix);
cols = columns(matrix);
for i = 1:rows
for j = 1:cols
fprintf(outputFile, sprintf(precision_format{j,1}, matrix(i,j)));
if (j ~= cols)
fprintf(outputFile, space_between_columns);
end
end
if i ~= rows
fprintf(outputFile, "\n");
end
end
fprintf(outputFile, "\n");
else
disp("STOP!, you invoked display_rounded_matrix with bad parameters");
end
elseif (nargin == 3 && outputFile == 0)
%print to screen instead
if (rows(precision) == 1 && columns(precision) == 1)
rows = rows(matrix);
cols = columns(matrix);
format = strcat(format_part, num2str(precision), "f");
for i = 1:rows
for j = 1:cols
printf(sprintf(format, matrix(i,j)));
if (j ~= cols)
printf(space_between_columns);
end
end
if i ~= rows
printf("\n");
end
end
printf("\n");
elseif (rows(precision) == 1 && columns(precision) == columns(matrix))
%here we have to custom make the rounding
rows = rows(matrix);
cols = columns(matrix);
for i = 1:rows
for j = 1:cols
%format = strcat(format_part, num2str(precision(1,j)), "f");
format = [format_part num2str(precision(1,j)) "f"];
printf(sprintf(format, matrix(i,j)));
if (j ~= cols)
printf(space_between_columns);
end
end
if i ~= rows
printf("\n");
end
end
printf("\n");
else
disp("STOP!, you invoked display_rounded_matrix with bad parameters");
end
elseif (nargin == 2)
display_rounded_matrix(matrix, precision, 0);
else
disp("STOP!, you invoked display_rounded_matrix with wrong number of arguments");
end
end
Then you can invoke it like this:
然后你可以像这样调用它:
A = [ 53.0 410400 0.0094; 52.56 778300 -0.0069; 53.56 451500 -0.0340 ];
specified_rounding = [2 0 5];
display_rounded_matrix(A, specified_rounding, outputFile=0);
This will display the following on the screen (notice the different roundings for each column!
这将在屏幕上显示以下内容(注意每列的不同四舍五入!
octave:5> display_rounded_matrix(A, specified_rounding, outputFile=0);
53.00 410400 0.00940
52.56 778300 -0.00690
53.56 451500 -0.03400
the 3rd parameter is a file handle, you could redirect the output to a file too:
第三个参数是文件句柄,您也可以将输出重定向到文件:
outputFile = fopen("output.txt", "w");
A = [ 53.0 410400 0.0094; 52.56 778300 -0.0069; 53.56 451500 -0.0340 ];
specified_rounding = [2 0 5];
display_rounded_matrix(A, specified_rounding, outputFile);
Which will do the same thing as above, but send the output to output.txt
这将做与上面相同的事情,但将输出发送到 output.txt
回答by Ufos
for those who want to get it working without digging deep into discussion why things are this way (namely octave round
still does not support a second argument defining precision).
对于那些想要让它工作而不深入讨论为什么事情是这样的人(即八度round
仍然不支持定义精度的第二个参数)。
WORKAROUND:
解决方法:
a = [0.056787654, 0.0554464; 0.056787654, 0.0554464];
a
round_digit = 2;
if exist('OCTAVE_VERSION', 'builtin') ~= 0;
a = a.*(10^(round_digit));
a = floor(a);
a = a.*(10^(-round_digit));
else
a = round(a, round_digit);
end
a