将一个双精度数赋给一个浮点数变量

huangapple go评论124阅读模式
英文:

Assigning a double to a float variable

问题

我读过Java默认情况下将float c = 5.6;视为double,除非你指定f后缀。

public class Main {
  public static void main(String[] args) {
    float c = 3.1e2;
    System.out.println(c);
  }
}

在这段代码中,3.1e2是一个double,根据我所了解,由于Java默认情况下将每个float变量视为double,除非你指定f后缀,所以c也应该是一个double。但是,我得到一个错误,错误消息为
Main.java:3: error: incompatible types: possible lossy conversion from double to float float c = 3.1e2; ^ 1 error

英文:

I read that java treats float c = 5.6; as a double by default unless you specify the f suffix .

public class Main {
  public static void main(String[] args) {
    float c = 3.1e2;
    System.out.println(c);

  }
}

in this code 3.1e2 is a double and c should be also a double by default since i read that java will make every float variable a double by default unless you specify the f suffix .
But i get an error saying
Main.java:3: error: incompatible types: possible lossy conversion from double to float
float c = 3.1e2;
^
1 error

答案1

得分: 1

当你说 "我读到 Java 默认会将每个 float 变量变成 double" 时,那是不正确的,你可能读错了。Java 默认会将浮点数 变成 double。如果你写一个带小数点但没有 d 的字面值,它会假定你想要一个 double。在你的例子中,5.6 是一个默认为 double 的字面值。

然而,对于带类型的变量,没有默认值,它是你赋予的类型。在你的例子中,c 被声明为 float,所以它是一个 float,即单精度浮点数。

当你声明一个变量为 float 类型时,它会分配足够的空间来存储单精度浮点数。没有足够的空间来存储双精度浮点数,并且如果你使用强制转换来尝试,你将失去来自 double 值的额外精度。这就是发布的代码生成的错误在告诉你的,它提醒你会丢失数据。

英文:

When you say " i read that java will make every float variable a double by default ", that is incorrect, you must have misread. Java will make floating point values double by default. If you write a literal value with a decimal point but without a d then it assumes you want a d. In your example 5.6 is a literal that is a double by default.

However, there is no default for typed variables, it is whatever type you give it. In your example c is declared as a float, so it's a float, meaning single precision floating point.

When you declare a variable to be type float you get enough room allocated to store a single precision floating point number in it. There isnt enough room to fit a double precision floating point number into it, and if you use a cast to force it, you will lose the extra precision from the double value. Which is what the error generated by the posted code is telling you, it's alerting you that you would lose data.

答案2

得分: 1

回答你的初始问题,

> "我读到Java默认将float c = 5.6;视为double,除非你指定f后缀。"

它将_5.6_ 视为 double,而不是整个赋值语句—c 仍然是 float

这是来自 Java教程 的摘录。
基本数据类型 (The Java™ Tutorials > 学习 Java 语言 > 语言基础)

> "浮点字面值
>
> 如果浮点字面值以字母F或f结尾,则它的类型为float;否则,它的类型为double,可以选择以字母D或d结尾。

至于后续问题,

> "... 在这段代码中,3.1e2是double,按照我所了解,Java会将每个float变量默认转换为double,除非你指定f后缀。"

这部分是正确的。c 变量不会自动转换为 double
它将是声明类型,本例中是 float

> 浮点类型(float和double)也可以使用E或e(科学记数法)、F或f(32位浮点文字)以及D或d(64位双精度文字;这是默认的,按照约定通常省略)。"

最后,

> "但我得到一个错误,说
> Main.java:3: 错误: 不兼容的类型: 可能会丢失从double到float的精度转换"

这是因为从一个值到另一个值的推断转换会降低可行的精度。

_ Java语言规范_ 将此操作定义为 "缩小的原始转换"。
Java语言规范 - 第5章。转换和提升

> "缩小的原始转换可能会丢失有关数值的整体幅度的信息,也可能会丢失精度和范围。"

基本上,当它是一个 缩小 过程时,不会推断进行转换。
因此,它会引发编译器错误。

英文:

To answer you're initial question,

> "I read that java treats float c = 5.6; as a double by default unless you specify the f suffix ."

It treats the 5.6 as a double, not the entire assignment—c is still a float.

Here is an except from the Java Tutorial.
Primitive Data Types (The Java™ Tutorials > Learning the Java Language > Language Basics)

> "Floating-Point Literals
>
> A floating-point literal is of type float if it ends with the letter F or f; otherwise its type is double and it can optionally end with the letter D or d.

And, in terms of the follow-up question,

> "... in this code 3.1e2 is a double and c should be also a double by default since i read that java will make every float variable a double by default unless you specify the f suffix ."

This is partially correct.  The c variable will not be implicitly converted to a double.
It will be whatever the declaring type is—in this case a float.

> The floating point types (float and double) can also be expressed using E or e (for scientific notation), F or f (32-bit float literal) and D or d (64-bit double literal; this is the default and by convention is omitted)."

And, finally,

> "But i get an error saying
> Main.java:3: error: incompatible types: possible lossy conversion from double to float"

This is because the inferred cast, from one value to another, will reduce a plausible accuracy.

The Java Language Specification defines this operation as a, "narrowing primitive conversion".
Java Language Specification – Chapter 5. Conversions and Promotions.

> "A narrowing primitive conversion may lose information about the overall magnitude of a numeric value and may also lose precision and range."

Essentially, the conversion is not inferred when it is a narrowing procedure.
Thus, it throws a compiler error.

答案3

得分: 0

The literal 3.1e2 is treated as a double, which is then assigned to the float variable c, which is where you get your error.

Aside from tacking on that f suffix to the literal, you can explicitly cast to float:

float c = (float)3.1e2;
英文:

The literal 3.1e2 is treated as a double, which is then assigned to the float variable c, which is where you get your error.

Aside from tacking on that f suffix to the literal, you can explicitly cast to float:

float c = (float)3.1e2;

答案4

得分: 0

它将其视为double。然而,您将其分配给了一个float变量。

在某些情况下,C#和Java允许隐式转换;例如,以下情况是完全允许的:

class Main {
    public static void main(String[] args) {
        float c = 3.1e2f;
        System.out.println(c);

        double d = c;

        System.out.println(d);
    }
}

由于double是比float“更大”的数据类型,因此如果这样做,不会发生数据丢失的可能性。

但是,如果我尝试以下操作:

public class Main {
    public static void main(String[] args) {
        double c = 3.1e2;
        System.out.println(c);

        float d = c;

        System.out.println(d);
    }
}

我最终会得到与您相同的编译器错误。再次强调,这是因为double是比float“更大”的数据类型,因此double可能包含大于float的最大可能值的值。考虑以下代码示例:

public class Main {
    public static void main(String[] args) {
        double c = 10*(double)Float.MAX_VALUE;
        System.out.println(c);
    }
}

它会打印出 3.4028234663852886E39。现在,如果我尝试将其放入float中会发生什么?如果我执行以下操作,结果会是Infinity

public class Main {
    public static void main(String[] args) {
        float c = 10*Float.MAX_VALUE;
        System.out.println(c);
    }
}

正如您所看到的,行为是完全不同的。如果转换只是在您不知道的情况下“在后台”发生,您可能会得到各种意想不到的结果。

另请参阅:https://stackoverflow.com/questions/7544233/difference-between-implicit-conversion-and-explicit-conversion

英文:

It is treating it as a double. However, you're assigning it to a float variable.

In some cases, C# and Java will allow implicit conversion; for example, the following is perfectly allowable:

class Main {
    public static void main(String[] args) {
        float c = 3.1e2f;
        System.out.println(c);
        
        double d = c;
        
        System.out.println(d);
    }
}

Since a double is a "larger" type than a float, there's no possibility of data loss if you do that.

However, if I try to do the following:

public class Main
{
	public static void main(String[] args) {
		double c = 3.1e2;
        System.out.println(c);
        
        float d = c;
        
        System.out.println(d);
	}
}

I end up getting the same compiler error you got. Again, that's because a double is a "larger" data type than a float, so the double could contain a value that's larger than the maximum possible value for a float. Consider the following code sample:

public class Main
{
	public static void main(String[] args) {
		double c = 10*(double)Float.MAX_VALUE;
        System.out.println(c);
	}
}

It prints 3.4028234663852886E39. Now, what would happen if I tried to put that in a float? Well, if I do the following, the result is Infinity:

public class Main
{
	public static void main(String[] args) {
		float c = 10*Float.MAX_VALUE;
        System.out.println(c);
	}
}

As you can see, the behaviors are quite different. If a conversion simply happened "in the background" without you being aware of it, you could get all kinds of unexpected results.

See also: https://stackoverflow.com/questions/7544233/difference-between-implicit-conversion-and-explicit-conversion

答案5

得分: 0

以下是翻译好的内容:

如果您只想要简单的答案,不需要任何解释或其他内容,那么您的代码将如下所示...

float c = 3.1e2f;

System.out.println(c);

您说的有点部分不正确,因为在您的语句中,“我读到Java将float c = 5.6;默认视为double,除非您指定f后缀。”,实际上Java并不会将c视为double;c将是一个浮点变量,但由于将一个double值5.6分配给一个float,而float大于double,因此会出现错误。

英文:

If you just want a simple answer, without any explanation or anything, then your code will be as follows...

float c=3.1e2f;

System.out.println(c);

What you said is kinda partially incorrect, because in your statement, "I read that java treats float c = 5.6; as a double by default unless you specify the f suffix .", Java doesn't actually treat the c as double as well; c will be a floating point variable, but since a double value '5.6' is assigned to a float, and float is greater than double, thus the error.

huangapple
  • 本文由 发表于 2023年6月15日 05:45:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76477758.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定