Can you store a float in a 2D array?

Blitz3D Forums/Blitz3D Programming/Can you store a float in a 2D array?

Blitzplotter(Posted 2010) [#1]
I am suspecting that only integers can be stored directly into an array.

However I need to have a variable(an array...) that can be iterated through with numbers of the type of -0.1234567.

Can anyone be of assistance?


Warner(Posted 2010) [#2]
I don't believe that is possible, unless you mean like using Dim a#(100).
You could choose for a TMap: http://www.blitzbasic.com/codearcs/codearcs.php?code=2574
or maybe convert the numbers from floats to integers:
Dim Array$(2000)

SetArray(0.001, "hello")
SetArray(-0.123, "hi")

Print GetArray(0.001)
Print GetArray(-0.123)


Function SetArray(index#, value$)

	ind = Int(index * 1000 + 1000)	
	If ind < 0 Then RuntimeError "Out of range"
	If ind > 2000 Then RuntimeError "Out of range"
	Array(ind) = value

End Function


Function GetArray$(index#)

	ind = Int(index * 1000 + 1000)
	If ind < 0 Then RuntimeError "Out of range"
	If ind > 2000 Then RuntimeError "Out of range"
	Return Array(ind)

End Function

However, that last method implies a loss of precision.

It would also depend on how you want to use the array.
If you wanted to say
x(1) = 10
x(2) = 20

print x(1.5) --->result:15

Then you could make a function that interpolates between the two closest integer array entries.


puki(Posted 2010) [#3]
Just store them as strings.


Blitzplotter(Posted 2010) [#4]
thanks for both the suggestions, they are appreciated (;-)


Blitzplotter(Posted 2010) [#5]
But this works:-


Dim locationarray#(5000,1) ; note ,0=lat, 1=long



thanks to Ross C. What a great forum this is! And as you said warner Dim a#(100)


Warpy(Posted 2010) [#6]
I assume what you've actually got is something like time/distance pairs, so you want to be able to get the distance travelled at a particular time.
If that's what you want, you can store it in an array with as many columns as you have data points, and two rows. Think of it like two rows of an Excel spreadsheet. Getting the distance corresponding to a particular time just means reading down the row until you get to the right time, and reading off the distance from that column.

'initialise array to have 30 columns and two rows
Const numpoints = 30

Local data#[numpoints,2]

'generate some pretend data
Local time#,distance#
For c=0 To numpoints-1
	time :+ Rnd(1.0,2.0)
	distance :+ Rnd(0.3,0.4)
	data[c,0] = time
	data[c,1] = distance
Next


'this function fetches the distance travelled at a particular time
'it doesn't interpolate, so it'll round up to the closest data point
Function getDistance(time#,data#[,])
	Local c=0
	'go down the time row until you get to the requested time
	While c<numpoints And data[c,0]<time
		c:+1
	Wend
	
	'return the associated distance
	Return data[c,1]
End Function


As you're dealing with floats, it would be very easy to extend this to interpolate between data points.


puki(Posted 2010) [#7]
I'd take the string route.


_PJ_(Posted 2010) [#8]
Here's a workable, but unfinished (Actually displaying or using the information is only partial) system for 2D-Arrays of mixed data types (Float, Int or String):




Zethrax(Posted 2010) [#9]
You can store any data type in an array as long as you declare the array as being of that data type. You can only store the data type that the array was declared for, though.

eg. Dim MyArray#( 100, 100 )


Blitzplotter(Posted 2010) [#10]
All, thankyou for the feedback. @Warpy, your idea about incorporating 'all' the associated data into one array is a good one. I will put this slightly further down my project plan.... At the moment I am still stripping out data from an XML file. It is relatively easy now that I've stripped out the first few components (distance travelled, lat, long).

@Malice, my lawrd, thats one comprehensive little slice of code you've posted there, very much appreciated.

However it is easier (whilst prototyping, erm some may say 'hacking' with all the plans in my noggin) to digest one .dat file containing one particular type of data for the time being.

Once I sew it all together the sweet resolution would be to have everything in one array saved to the one mammoth .dat file. In fact, it would be easier to do it on the fly from the XML file however there is a little time required to process all the data from the XML file. Therefore, I'll stick with the import option.


_PJ_(Posted 2010) [#11]
Another option, provided tyou are not using strings, may be to store the 4-bytes 'word' which can be interpreted as an Int or Float as required.


Leon Drake(Posted 2010) [#12]
@puki you can use string handles for arrays like php in blitz?? i didn;t know that


Blitzplotter(Posted 2010) [#13]
It is going great, this is what my .dat file contains:-

lat53.0482long0.0
lat0.0long-0.38498
lat53.0482long0.0
lat0.0long-0.384979
lat53.0483long0.0
lat0.0long-0.384978
lat53.0484long0.0
lat0.0long-0.384923
lat53.0485long0.0
lat0.0long-0.384867
lat53.0486long0.0
lat0.0long-0.384869
lat53.0489long0.0
lat0.0long-0.384856


However, it seems as though the default float in Blitz3D is 7 digits within it (including the decimal point). My XML file has lat & longs has typically got 10 places :-

              <LatitudeDegrees>53.0482863</LatitudeDegrees>
              <LongitudeDegrees>-0.3849778</LongitudeDegrees>


Is there a way to expand the size of the default float Blitz3D uses?

Thanks in advance, if not I may resort to Puki's option of saving the string.


Warner(Posted 2010) [#14]
I believe you can do that with this DLL, however, I never tried it:
http://www.blitzbasic.co.nz/codearcs/codearcs.php?code=1905


Floyd(Posted 2010) [#15]
The question is how much accuracy do you really need. Are all those digits in the XML file meaningful? That seems very unlikely.

For example, the latitude 53.0482863 has a final digit of 3. Is it really significant? If it were changed to a 2 or a 4 the corresponding change in position ( I'm assuming this is the Earth ) would be less that four millimeters. I doubt anything was really measured with that much precision.

Single precision floats are probably good enough. If not then you are using the wrong language. As mentioned you can use a DLL to get higher precision. But it is awkward and you will get tired of it very quickly.


Blitzplotter(Posted 2010) [#16]
Thanks for the additional feedback, I found the following:-


Avoid excessive precision (0.0001° is <11 m, 1 inch is <31 m).



Hmm, I'm thinking I may have sufficent precision with four decimal places, which is more than sufficient for my goal with Blitz3D. Thanks for the extra feedback/stimulus!

And yep, your right Floyd it is the earth, I like a challenge but I'm not sure I'm gonna crack having a run on Mars in my lifetime - but you never know - Heh he(;-)

KML looks interesting:-

http://en.wikipedia.org/wiki/Keyhole_Markup_Language


Chroma(Posted 2010) [#17]
Floyd is making sense. I think the amount of precision loss would be negligible. But it all depends on how much of a perfectionist you are. :)


Axel Wheeler(Posted 2010) [#18]
You couldn't use either the lat or long as a lookup anyway unless there are no repeats, which there appear to be in your sample above. Still it looks like you weren't really looking for a lookup, but rather just storing floats in the array.

Did you say the file was XML? Consider using John J.'s excellent BlitzXML:

http://www.blitzbasic.com/codearcs/codearcs.php?code=1393

Also consider using a type to store the data:

Type Location
   Field Latitude#
   Field Longitude#
End Type

Function LoadStuff()
   ;Assuming a massaged .txt file, not xml
   fileIn=ReadFile("file.txt")
   While Not Eof(fileIn)
      l.location = new location
      l\latitude=ReadShort(fileIn)
      l\longitude=ReadShort(fileIn)
   Wend
   CloseFile(fileIn)
End Function


If the file contains other stuff as in your sample, you might have to
tmp$=ReadLine(fileIn) 

(imports as a string) instead and parse it with Left$(), Mid$(), and Right$() to get rid of the extra junk. Then...

l\latitude=tmp


will cast it back to a float.

As far as precision is concerned, I don't know how blitz will respond to attempting to load double-precision floats. Will it just drop the extra digits (which seems to be what you want) or will it do something ... bad? Like take a totally wrong value, or format your hard drive. Something like that. :-) If so, just use the tmp.txt method and

l\latitude=Left$(tmp.txt,6)


should convert only the first six characters (including the period) into the float. Or however many you want. I haven't tried doing that in one line like that, but it should work...

Good luck.

-Pete


Blitzplotter(Posted 2010) [#19]
Thanks pete, will try later this week. My heart rate data is buggy....