Blueprint does not have "double" type?

Hello,

so I was trying to have a pretty simple UFUNCTION which has a return type double where I suddenly realized that there is no “double” type in Blueprint?! Strangely enough my UFUNCTION got compiled and what I saw was a “bad_type” error in blueprint:

Is it by design that we don’t have double type? I’m using the latest QA4.4 build.

Yep, some types can’t be used as BP pins.
You can’t use doubles, delegates and some others. The BP will be constructed but will give compile errors if using those as pins.

Hi ,

Doubles are currently not usable in Blueprints. This is mainly done to simplify Blueprint use for non-programmers. There is some discussion going on internally in regards to exposing doubles to Blueprints, but I do not know when, or even if, this will happen.

Hi ,

thanks for fast response. It is rather confusing not to have a basic type in BP and I still don’t quit understand how is float less confusing for non-programmers than double. But I guess we will have to use float for now.

The main goal was to expose only a single type for each kind of numeric value. That we chose float instead of double and int32 instead of, say, int64 is purely historical, because in UnrealScript in earlier versions of Unreal Engine, those larger types were not available at all.

We are increasingly seeing the disadvantages of this and are seriously considering to update all fundamental BP types to the largest available types, i.e. double and int64. Some more discussion is needed as the impact of this change would be rather large.

+1 for double (and double*) in Blueprints.

bump for double because the float error is so annoying

We are still considering the option of using the larger data types (double, int64) in Blueprints. Unfortunately this would be a very large change within the Engine, and we do not have a timeframe on when we may attempt to make this change.

Hello,

i am still learning to make game with ue4 editor and i see that i cant use uint64 or int64 variables :frowning:

someone made a “wrapper” (KeshUE4FundamentalTypeWrapperPlugin/KeshUE4FundamentalTypeWrapper.h at master · Daekesh/KeshUE4FundamentalTypeWrapperPlugin · GitHub)

but i dont know if i can use this for my problem ? may i do variable1+variable2 = variable3 in blueprint with this wrapper with variable1 variable2 and variable3 as uint64 ? is there any tutorial how to use this in my project so i can use uint64? i am so lost right now since i only use blueprint only project :frowning:

Hi skeleton60,

I took a real quick glance at the plugin that you linked, and it appears to be doing a lot of casting internally to allow the use of other data types that are not directly supported by Blueprints. While this may work fine, you should be aware that casting can potentially result in lost data or unexpected results. This is particularly dangerous in situations where you are casting from a larger data type (uint64, for example) to a smaller type (int32, which is supported by Blueprints). If the value stored in the uint64 variable is larger than the maximum value that can be stored in an int32 variable, you will run into problems with integer overflow.

If you are new to game development and using Blueprints only, it may be best to just use the data types that are supported by Blueprints by default. This will remove the need to understand the plugin you mentioned, and should reduce any confusion that you may have.

Sorry to bump an old post, but another good reason for this feature is that a lot of third party libraries use other numeric types, and it makes it impossible to define data for those things in blueprints. With double support you’d be able to store the entire range of values for all 32 bit number types despite the type difference.

That said something that might be nice and keep blueprints simple is to support extra numeric blueprint types, but only if they’re defined in C++. That way people who use blueprint only won’t ever need to know about it. What I really need more than anything is just to have types supported in blueprints as editable fields, but pins and members defined from blueprint aren’t really important as I’m passing them to third party libraries in C++ anyway.

Just wanted to add to the voices that would support this feature :slight_smile:

Hi mrooney,

There are some definite benefits that we can see to supporting Doubles in UE4, and there are a handful of Engineers here who are pushing for us to support them. Unfortunately Floats have been an integral part of the Engine for so long that there is a vast amount of inertia that must be overcome in order to start making the change. Floats are used literally everywhere in Blueprint code, and adding support for Doubles would either require vast areas of source code to be updated, or any function using a Float would need to be overloaded with a version using a Double instead. In addition, any projects started prior to the change would need to be reworked if they wanted to use Doubles instead of Floats. As beneficial as the change may be for everyone using the Engine, it is not a change that we would be able to make quickly, nor without a great deal of planning.

Hi , I want to add mrooney’s suggestion. Instead of converting float to double and int32 to int64, why not just keep them they way it is in Blueprint, but change them when they are compiled? So people will still see float and integer types, but during compilation, the compiler will automatically convert them to 64-bit data types.

I believe there are thousands of game developers out there dying to get this feature working in UE. Especially knowing that every OS in the market soon will migrate fully to 64-bit system. Perhaps in the next 5 years or so, support for 32-bit numbers will diminish.

So instead of recoding everything in UE, just change the behavior of the compiler to treat every 32-bit data type into 64-bit data type.

Normally, iOS uses Objective-C and Android uses Java. Conceptually, UE uses C++ but can generate binary codes to support both iOS and Android. So technically, you guys can modify the behavior of the compiler to do this.

You are forgetting the implications of casting every int32 to int64. First, how are you going to feed a 64 bit number if the runtime value is limited to 32 bits? Second, you completely ruin memory optimizations and unnecessarily double your memory footprint. You mentioned iOS and Android but I think you forgot to consider that these devices don’t have 8 gigs of RAM. Hell, you’ll be lucky if you have more than 1GB.

There aren’t really any benefits of adding uint32/64, double, and int64. Chances are if you know how and when to use those data types you likely need to be using C++ anyway (yes I realize the generalization of this statement).

Hi Pelangi,

As Shohei mentioned, there are some drawbacks to your suggestion that may not be immediately obvious. First, any conversions of data types from larger to smaller types runs the risk of data loss. Even if you are only simulating the appearance of an int32 variable when it is actually an int64 variable, when that variable gets passed into Engine functions it will need to be converted to an int32 in order to work since the variable types in the Engine would not have been changed.

There would also be an additional cost in terms of performance whenever a variable is passed into, or returned from, an Engine function as the conversion takes place.

Unfortunately there would not be a feasible way to have the compiler convert the data types during compile time. Doing so would require that the Engine be rebuilt every time a project is rebuilt, and trying to automatically change data types for a program as complex as the Engine would be incredibly risky. The only way to minimize the risk of data loss and performance cost would be to completely replace the variable types in the Engine source code.

+1 for double

+1 for double support and move discussion to pipeline already! :smiley: Way too much people are asking for them. While most of simple stuff can be done in floats for more delicate stuff (and there is plenty of) one just need to have that double. Please make it happen, pretty please :slight_smile:

bump for double

You can write your own.

UE4KitMathBPLibrary.h

// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

#pragma once

#include "Engine.h"
#include "UE4KitMathBPLibrary.generated.h"

/* 
*	Function library class.
*	Each function in it is expected to be static and represents blueprint node that can be called in any blueprint.
*
*	When declaring function you can define metadata for the node. Key function specifiers will be BlueprintPure and BlueprintCallable.
*	BlueprintPure - means the function does not affect the owning object in any way and thus creates a node without Exec pins.
*	BlueprintCallable - makes a function which can be executed in Blueprints - Thus it has Exec pins.
*	DisplayName - full name of the node, shown when you mouse over the node and in the blueprint drop down menu.
*				Its lets you name the node using characters not allowed in C++ function names.
*	CompactNodeTitle - the word(s) that appear on the node.
*	Keywords -	the list of keywords that helps you to find node when you search for it using Blueprint drop-down menu. 
*				Good example is "Print String" node which you can find also by using keyword "log".
*	Category -	the category your node will be under in the Blueprint drop-down menu.
*
*	For more info on custom blueprint nodes visit documentation:
*	https://wiki.unrealengine.com/Custom_Blueprint_Node_Creation
*/
UCLASS()
class UUE4KitMathBPLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_UCLASS_BODY()

private:

	static FString DoubleToString(double InDouble);

public:

	/* Double Addition (A + B) */
	UFUNCTION(BlueprintPure, meta = (DisplayName = "double + double", CompactNodeTitle = "+", Keywords = "double + add plus", CommutativeAssociativeBinaryOperator = "true"), Category = "UE4Kit|Math|Double")
	static FString Add_DoubleDouble(const FString& A = "1.0", const FString& B = "1.0");

	/* Double Subtraction (A - B) */
	UFUNCTION(BlueprintPure, meta = (DisplayName = "double - double", CompactNodeTitle = "-", Keywords = "double - subtract minus"), Category = "UE4Kit|Math|Double")
	static FString Subtract_DoubleDouble(const FString& A="1.0", const FString& B = "1.0");

	/* Double Multiplication (A * B) */
	UFUNCTION(BlueprintPure, meta = (DisplayName = "Double * Double", CompactNodeTitle = "*", Keywords = "double * multiply", CommutativeAssociativeBinaryOperator = "true"), Category = "UE4Kit|Math|Double")
	static FString Multiply_DoubleDouble(const FString& A = "1.0", const FString& B = "1.0");

	/* Double Division (A / B) */
	UFUNCTION(BlueprintPure, meta = (DisplayName = "Double / Double", CompactNodeTitle = "/", Keywords = "double / divide division"), Category = "UE4Kit|Math|Double")
	static FString Divide_DoubleDouble(const FString& A = "1.0", const FString& B = "1.0");
};

UE4KitMathBPLibrary.cpp

// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.

#include "UE4KitMathModule.h"
#include "UE4KitMathBPLibrary.h"

UUE4KitMathBPLibrary::UUE4KitMathBPLibrary(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{

}

FString UUE4KitMathBPLibrary::DoubleToString(double InDouble)
{
	// Avoids negative zero
	if (InDouble == 0)
	{
		InDouble = 0;
	}

	FString TempString;
	// First create the string
	TempString = FString::Printf(TEXT("%.8lf"), InDouble);
	const TArray< TCHAR >& Chars = TempString.GetCharArray();
	const TCHAR Zero = '0';
	const TCHAR Period = '.';
	int32 TrimIndex = 0;
	// Find the first non-zero char in the array
	for (int32 Index = Chars.Num() - 2; Index >= 2; --Index)
	{
		const TCHAR EachChar = Chars[Index];
		const TCHAR NextChar = Chars[Index - 1];
		if ((EachChar != Zero) || (NextChar == Period))
		{
			TrimIndex = Index;
			break;
		}
	}
	// If we changed something trim the string
	if (TrimIndex != 0)
	{
		TempString = TempString.Left(TrimIndex + 1);
	}
	return TempString;
}

FString UUE4KitMathBPLibrary::Add_DoubleDouble(const FString& A, const FString& B)
{
	double A_double = FCString::Atod(*A);
	double B_double = FCString::Atod(*B);
	double C_double = A_double + B_double;
	return 	UUE4KitMathBPLibrary::DoubleToString(C_double);
}

FString UUE4KitMathBPLibrary::Subtract_DoubleDouble(const FString& A, const FString& B)
{
	double A_double = FCString::Atod(*A);
	double B_double = FCString::Atod(*B);
	double C_double = A_double - B_double;
	return 	UUE4KitMathBPLibrary::DoubleToString(C_double);
}

FString UUE4KitMathBPLibrary::Multiply_DoubleDouble(const FString& A, const FString& B)
{
	double A_double = FCString::Atod(*A);
	double B_double = FCString::Atod(*B);
	double C_double = A_double * B_double;
	return 	UUE4KitMathBPLibrary::DoubleToString(C_double);
}

FString UUE4KitMathBPLibrary::Divide_DoubleDouble(const FString& A, const FString& B)
{
	double A_double = FCString::Atod(*A);
	double B_double = FCString::Atod(*B);
	double C_double = A_double / B_double;
	return 	UUE4KitMathBPLibrary::DoubleToString(C_double);
}

+1 for Double variable type, this will definitely be helpful when trying to get exact values without floating point problems and is super important!