将float从Java传递到JNI,额外的小数 [英] Passing float from Java to JNI, extra decimals

查看:699
本文介绍了将float从Java传递到JNI,额外的小数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个JNI应用程序。

I have a JNI application.

在Java实现中,我有以下

In the Java implementation, I have the following

float floatValue = 23.45f;
Object[] objArray = new Object[] { floatValue } ;

当我调用一个本地方法,传递我的对象数组,并在CPP中,我做以下:

When I call a native method, passing over my object array, and in CPP I do the following:

JNIEXPORT void JNICALL Java_my_method(JNIEnv * env, jobject objInstance, jobjectArray objArray){
    jclass floatClass = env->FindClass("java/lang/Float"); 
    jmethodID floatMethod = env->GetMethodID(floatClass, "floatValue", "()F");
    jobject obj = env->GetObjectArrayElement(objArray, 0);
    jfloat val = env->CallFloatMethod(obj, floatMethod);
    printf("JNI received float value: %f\n",val);
}

打印:

JNI received float value: 23.450001

/ p>

Any ideas?

推荐答案

我可以想出三种不同的方式来查看 float

I can think of three different ways of looking at what a float represents.


  • 您可以说 float 是一个精确的值,构成 float 的0和1的数字以二进制表示。 float 由尾数,指数和符号位组成,你可以通过数学将这些0和1转换为实数。这是查看 float 最常见的方式,大多数人会认为它是最正确的方式。

  • 一个 float 表示一个范围的值 - 基本上所有更接近 float 的数字比任何其他。当你使用 float 来测量某些东西时,这很有用。

  • 你可以想到 float 表示该范围内具有最小十进制扩展的特定数字。这个想法充满了问题,但它影响了Java与浮点的工作方式。

  • You can say that a float is an exact value, which is the number that the 0's and 1's that make up the float represent in binary. A float is made up of a mantissa, an exponent and a sign bit, and you can do the mathematics to turn those 0's and 1's into an actual number. This is the most common way of looking at a float, and most people would consider it the most correct way.
  • You can think of a float as representing a range of values - basically all the numbers that closer to that float than to any other. This is useful when you've used a float for measuring something.
  • You can think of a float as representing the particular number within that range, which has the shortest decimal expansion. This idea is fraught with problems, but it has influenced the way Java works with floating point.

因此,请考虑 x = 23.450000762939453125 。这个数字恰好由 float 表示,我将称为 f - 也就是break f 到它的尾数和指数,进行计算, x 将会出来。

So consider the number x = 23.450000762939453125. This number happens to be represented exactly by a float, which I'll call f - that is, break f into its mantissa and exponent, do the calculation, and x will come out.

c $ c> x ,可以通过一个float来精确表示 x - h = 23.4499988555908203125 。并且可以通过float精确表示的 x 下面的数字是 x + h = 23.4500026702880859375 。我刚刚使用 h 来表示连续 float 数字之间的差距。

The next number below x that has can be represented exactly by a float is x - h = 23.4499988555908203125. And the next number above x that can be represented exactly by a float is x + h = 23.4500026702880859375. I've just used h to denote the gap between consecutive float numbers around this magnitude.

现在,如果您在 x - h / 2 = 23.44999980926513671875 范围内有任何数字,最多 x + h / 2 = 23.45000171661376953125 ,那么最接近您的号码的 float 将是 f 。所以这是由 f 表示的数字范围 - 当然, x 正好在这个范围的中间。

Now, if you have any number in the range x - h / 2 = 23.44999980926513671875 up to x + h / 2 = 23.45000171661376953125, then the closest float to your number will be f. So that is the range of numbers that are represented by f - and of course, x is right in the middle of this range.

您会注意到 23.45 在该范围内,因此 23.450001 。这意味着如果你使用Java float literal 23.45F ,它的值实际上是f 。 Java float literal 23.450001F 也是如此。这就是为什么表达式(23.45F == 23.450001F)的原理是 true

You'll notice that 23.45 is in that range, and so is 23.450001. What that means is that if you take the Java float literal 23.45F, its value is in fact f. The same is true of the Java float literal 23.450001F. And that's why the expression (23.45F == 23.450001F) works out to be true.

现在,当我们尝试打印这个 float number f 时,事情开始得到不同的C ++和Java。

Now, when we try to print this float number f, things start to get different between C++ and Java.


  • 在C ++中,打印 float 的默认方式是查找数字它表示精确,并将其舍入到六个小数位。所以你得到的是 x 四舍五入到小数点后六位,当然是 23.450001

  • 在Java中,打印 float 的默认方式是使用最小的十进制扩展找出所表示范围内的数字。换句话说,Java将寻找 x - h / 2 x + h / 2 之间的数字可以用最小的小数位数写入。这个数字是 23.45

  • In C++, the default way of printing a float is to find the number that it represents exactly, and round it to six decimal places. So what you get is x rounded to six decimal places, which of course is 23.450001.
  • In Java, the default way of printing a float is to find the number within the represented range, with the shortest decimal expansion. In other words, Java will look for the number between x - h / 2 and x + h / 2 that it can write with the smallest number of decimal places. This number is 23.45.

f 为 23.450001 ,除非您特别指示程序以不同方式显示。任何Java程序将显示 f 23.45 ,除非您特别指示程序以不同方式显示。但它都是一样的 float

So any C++ program will show f as 23.450001, unless you specifically instruct the program to show it differently. Any Java program will show f as 23.45, unless you specifically instruct the program to show it differently. But it's all the same float.

这篇关于将float从Java传递到JNI,额外的小数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆