For floating-point types you could use +/-Infinity or NaN (quiet or signaling) depending on your use case:
The problem with NaN is, it does not get picked up by the typechecker.
Of course, because NaN is not a type. It is a specific floating-point value that informs that something went wrong in the calculation. To protect yourself against problems in the code, there are special magic statements for this purpose - for example:
if 
If someone in their code does not use instructions checking the values of variables or the results of operations, then they have problems.
If you use an explicit nullable type, you know that the function can return null, so it also serves as documentation, but most importantly, the typechecker forces you to unpack the nullable, requiring you to handle null values.
"Nultable" types are not a solution to the problem, but a way of covering or masking it (like sealing a hole in a pipe with a piece of chewing gum). It's pretending that the problem has been solved. A trendy and nasty solution characteristic of the current times, which came from typeless scripting languages. It reminds me of solutions from PHP, where many functions (usually) return a result in the form of a number (e.g. when searching a string of characters). But sometimes such a function returns False or something even more exotic instead of a number (e.g. -1). It's a mess, a dump.
And because C# or Pascal have types, prostheses were created, in the form of so-called nullable "types". An idiotic solution, pretending to be a solution, but in reality causing confusion. Since the function returns a result of the Double type, there is no reason for it to return an empty pointer. A pointer is not a floating-point number.
And since C# and Pascal have types, prosthetics were created, in the form of so-called nullable "types". An idiotic makeshift solution, pretending to be a solution but actually causing confusion. Since the function returns a Double result, there is no reason for it to return an empty pointer. A pointer is not a floating-point number. A function that can return a result of different types is a recipe for disaster. Where is Pascal's strictness of syntax here?
If you just see the function declaration:
function GetLineSlope(const P1, P2: TPoint): Extended;
Do you know the function can return NaN? Do you need to handle that case?
Of course, this is expected. Because NaN can be (is) used in various libraries (e.g. in Math). And it can (but does not have to) be returned by some functions operating on real numbers. You just have to check it.
Well you can't know without looking into the function or additional documentation. If you see:
function GetLineSlope(const P1, P2: TPoint): TNullable<Extended>;
But that doesn't help at all. Because you have to check if the function didn't return an empty pointer instead of a floating point number. This is a much worse solution.
You know exactly that the author of the function intends to return null in some cases and the compiler "forces" you to check against it
And its Author forces me to check if the result is not an empty pointer. So I gained nothing. This code checking for that unfortunate NaN would probably be simpler. But there is probably a more elegant solution: checking the contents of variables before performing arithmetic operations according to basic rules of mathematics (e.g. "remember, damn it, don't divide by 0").
The idea of returning results from functions in the form of two different primitive types (e.g. a floating-point number and a pointer) is one of the most idiotic ideas of the last decades. A function that previously returned results of a primitive type (one type!) can suddenly start returning a result of two primitive types. And when? It depends on what it calculates. Such solutions are a complete mess. It also requires inserting additional instructions that will protect your program from crashing when the function returns an empty pointer. Let's assume that a numerical computation library is created that uses this ugly prosthesis. I can already see complaints about the efficiency of calculations or the need to encapsulate calls to such functions with code that checks for empty pointers. A wonderful solution!