I have been reviewing asm.js, and I know one of the thing it does is use bit-wise operations to force numbers to be integers
If instead of
<cfreturn x>
If I
<cfreturn BitOr(x,0)>
Does this ensure that I am returning only integers as opposed to a float representation of an integer?
You can use JavaCast() to ensure that only integers are returned from ColdFusion.
<cfreturn JavaCast( "int", x )>
Depending on the version of ColdFusion, you may have an issue with serializeJSON() converting that value to a string though. In that case, then Miguel's suggestion of using parseInt() in your JavaScript would apply.
Related
I was wondering whether ColdFusion uses any binary search algorithm for searching? Does anyone of you have any idea on in-built functions and what they use?
Coldfusion lets you use anything in the Java standard library.
<cfset arr = [1, 2, 3, 4]>
<cfset collections = createObject('java', 'java.util.Collections')>
<cfdump var="#collections.binarySearch(arr, 3)#">
Keep in mind that the returned value is zero-indexed, while CF is one-indexed.
You may need to do more complicated conversions depending on the data types inside your array, and of course the array must be sorted before you use binarySearch.
This question already has answers here:
How can I prevent SerializeJSON from changing Yes/No/True/False strings to boolean?
(7 answers)
Closed 6 years ago.
I'm currently setting a number of variables like so:
<cfset printPage = "YES">
Eventually, when I print these variables out, anything that I try to set to "YES" prints out as "true". Anything set to "NO", prints out as "false". I'm not opposed to using the YesNoFormat function. In fact I might end up using that function in this application, but in the mean time I would like to know if ColdFusion is actually storing the words "YES" and "NO" in memory, or if it is converting them to a boolean format behind the scenes.
If CF is storing my variables exactly the way that I declare them, how would I go about retrieving these variables as strings? If CF is changing the variables in some way, are there any special characters or keywords that I could use to force it to store the variables as strings?
Thank you to everyone that commented / answered. I did a little more experimenting and reading, and it seems that the serializeJSON function will automatically convert "Yes" to "true" and "No" to "false". I either need to deal with this problem in my javascript, or I can add a space in the affected properties to circumvent this behavior.
You already know how to display the boolean value as "yes" or "no" (using YesNoFormat()). I don't think there is a way to force ColdFusion to store a variable a certain way. It just doesn't support that. I guess you could call out the Java type directly by using JavaCast(). I just don't see why you would want to go through that extra work for something like this. You can certainly research that a bit more if you like. Here is a link to the document for JavaCast.
Have a look at this document regarding data types in ColdFusion. I will post some of the relevant points from that document here but please read that page for more information.
ColdFusion is often referred to as typeless because you do not assign types to variables and ColdFusion does not associate a type with the variable name. However, the data that a variable represents does have a type, and the data type affects how ColdFusion evaluates an expression or function argument. ColdFusion can automatically convert many data types into others when it evaluates expressions. For simple data, such as numbers and strings, the data type is unimportant until the variable is used in an expression or as a function argument.
ColdFusion variable data belongs to one of the following type categories:
Simple One value. Can use directly in ColdFusion expressions. Include numbers, strings, Boolean values, and date-time values.
Binary Raw data, such as the contents of a GIF file or an executable program file.
Complex A container for data. Generally represent more than one value. ColdFusion built-in complex data types include arrays, structures, queries, and XML document objects. You cannot use a complex variable, such as an array, directly in a ColdFusion expression, but you can use simple data type elements of a complex variable in an expression. For example, with a one-dimensional array of numbers called myArray, you cannot use the expression myArray * 5. However, you could use an expression myArray[3] * 5 to multiply the third element in the array by five.
Objects Complex constructs. Often encapsulate both data and functional operations.
It goes on to say this regarding Data Types:
Data type notes
Although ColdFusion variables do not have types, it is often convenient to use “variable type” as a shorthand for the type of data that the variable represents.
ColdFusion provides the following functions for identifying the data type of a variable:
IsArray
IsBinary
IsBoolean
IsImage
IsNumericDate
IsObject
IsPDFObject
IsQuery
IsSimpleValue
IsStruct
IsXmlDoc
ColdFusion also includes the following functions for determining whether a string can be represented as or converted to another data type:
IsDate
IsNumeric
IsXML
So in your code you could use something like IsBoolean(printPage) to check if it contains a boolean value. Of course that doesn't mean it is actually stored as a boolean but that ColdFusion can interpret it's value as a boolean.
I use the # symbol around every dynamic value in my application and after posting some of my code on here for help, I've been told there's no need to use the # in many places e.g. <cfif> statements.
So I have started removing the # symbols, until I realised I broke my application because I removed the # symbols from the value="" attribute of a <cfprocparam> tag.
I am confused as to:
Why use the # symbol is some places and not others (and what is the benefit of not using it?)
Why if they are not required in <cfif> and <cfargument> tags are they suddenly required in <cfprocparam> tags?
Due to this lack of consistency, is it not better to just wrap hashes around every dynamic value in the first place?
There is no inconsistency (or very little: none of what you cite are inconsistencies), it's just you not understanding the rules (which are pretty basic really). It's all in the docs: "Using number signs"
In short, within a CFML statement, all elements are considered CFML, so there is no need to specifically mark them as such. EG:
<cfset myVar = someFunction(anArgument)>
There is no ambiguity there that myVar, someFunction and anArgument are anything other than CFML constructs, so no need to do this sort of thing:
<cfset myVar = #someFunction(anArgument)#>
As some people are inclined to do.
In the middle of text or within a string, there is ambiguity as to what's text and what's CFML, so one needs to use pound signs to mark them as such. EG:
<cfset myVar = "The time is #now()#">
It's necessary to us pound-signs there to disambiguate now() as being a CFML statement, an not just part of the string, eg:
<cfset myVar = "CFML has a function now() which returns the current timestamp">
Equally:
<cfquery>
SELECT col1
FROM table2
WHERE col2 = #someValue#
</cfquery>
There would be no way of knowing someValue is a variable there without marking it as such.
That's basically it. It's not complicated.
Rule 1: If you are inside of quotes, then you are pushing a string. If you want a substitution, the you use #name#
Rule 2: If you are inside of a <cfoutput>, you are generating a string.
While it is possible to write
<cfif "#name#" EQ "bob">Hi Bob</cfif>
It is easier to write
<cfif name EQ "bob">Hi Bob</cfif>
Rule 3: I think that <cfoutput query="qryData"> is kinda wrong, I have written it so much, I don't think much of it.
The # symbol is required around a variable only when you need to evaluate the contents of that variable. For example, when you need to out put that variable in a view.
You don't need them in cfset or cfif because the content of the variables is used in the Set or comparison.
You shouldn't be using the value of variables in the cfargument tag. You might however pass in a variable to as an argument without first evaluating it eg. myFunction(myarg=myVariable)
Cfprocparam you need to pass the value. You may be confusing how you're passing the variable and the value.
Value="myVar" would pass "myVar" as the value, where as value="#myVar#" would evaluate myVar and pass its content to value. value=myVar would pass myVar to value.
No real inconsistencies in the examples you give. That's not to say that there aren't a few inconsistencies kicking around in ColdFusion. ;)
Don't be hashing everything. It's messy and means that you add an evaluation step in everything bit of code you write.
Are there any known functional or performance differences in using yes|no vs. true|false?
ColdFusion documentation states that values for boolean-type attributes are specified with yes/no. For example, <cfargument required="yes|no" ....> I have used true and false in place of yes|no and have seen no unexpected functionality.
[EDIT]
I appreciate the responses, perhaps I am thinking a bit more general in this case.
ColdFusion documentation states that the expected value is 'yes|no' for some parameters, such as for cfargument required. Is there any insight into why yes|no is documented as the only expected values, rather than also true|false or stating 'any boolean value' is expected? Seems a bit ambiguous to not indicate any boolean type rather than only state 'yes|no' if either A)We are to assume 'any boolean' B)There is an actual performance difference. Thoughts?
ColdFusion evaluates yes/no, true/false, 1 (or any non-zero number)/0 equally. This makes it easy to make shortcut booleans like <cfif myquery.recordcount> or <cfif len(FORM.myVar)> without having to convert the integer into a true/false.
"yes/no" is a few characters less to type.
"true/false" (and true/false) is more in line with other programming languages.
In terms of performance, they are all strings as far as CF is concerned. It is not until you try to use them in conditional logic that they magically change into other data types, like java.lang.Boolean. The conversion between strings and Booleans and back again is very fast. It's what CF does most of the time. You'd be hard pressed finding any reliable tests proving one faster than the other.
For code maintainability/readability it's best to stick with one or the other.
Some legacy CF tag functions specifically require "yes/no". They simply will not work with "true/false". I believe this is no longer the case in CF9+.
Don't rely on the ColdFusion documentation being accurate or up to date. Almost all of the methods that list "yes/no" as the default/allowed values actually support any kind of boolean value. "yes/no", "true/false", true/false, 1/0, etc.
IMHO using "yes/no" for booleans is crazy. Backwards compatibility from the old CF5 era. Sucks that Adobe are still using it to output java Booleans.
eg. writeDump( var: (not true) ); gives you "NO". But, I wanted false?! Grrr.
You can tell what java class your variable is currently by calling myVar.getClass().getName(). You can use it to watch CF casting your data from Boolean to String and back to Boolean again, like magic.
As an experiment, you could try this. For me, ten million iterations of not using "yes" resulted in 100 fewer milliseconds for the most part.
<cfscript>
bln = true;
starttime = getTickCount();
for(i=0;i<10000000;i++){
if(bln eq true)
foo="bar";
}
writeOutput(getTickCount()-startTime & '<br />');
starttime = getTickCount();
for(i=0;i<10000000;i++){
if(bln eq "yes")
foo="bar";
}
writeOutput(getTickCount()-startTime & '<br />');
</cfscript>
We just upgraded a project to CF2016 and suddenly began getting java.lang.VerifyError "Incompatible argument to function" errors. Turned out to be in cfform, we were using accessible="true". Changing the value to "yes" does not remove the error. Removing the entire "accessible" form tag does. Rather than figuring out what Flash-related nightmare this represents, we removed it from our forms.
Thanks, Adobe.
I have a c++ program, I would like the first argument of the main (argv[1]) to correspond to a table of float. Is it possible to do that??
I was thinking about putting in a string my floats separated with spaces (e.g. "1.12 3.23 4.32 1.1 ...")
Is there a way to automatically convert such a string into a table of floats? If I understand well the atof function converts a string into a double. So it seems it could be possible to split my string using the spaces and then convert each portion using atof.
This option does not seem to be very efficient to me? In addition it returns double and not float :(
So, is there a better way to pass table of float as argument of a c++ program ?
Thank you
A stringstream can do both the splitting at spaces and the parsing into a float.
std::stringstream ss(the_string);
std::vector<float> v(std::istream_iterator<float>(ss),
(std::istream_iterator<float>()));
// the extra parentheses here are ugly but necessary :(
How to obtain the string with the data depends on how large it is and where it is supposed to come from. Just keep in mind that in many systems the arguments passed to program are already split by spaces, putting each part in a different element of argv.
Save it in a text file, and then read it from the file when your program starts. I isn't worth it to pass it as a command-line argument.
The main() parameter list is as it is. You can pass the strings of your numbers as arguments to your program. The main function will have to parse its argument.
When you want to pass a space separated list of numbers in argv[1] you can use the strtok function to get the individual number strings and have to pass it to a conversion function.
When your conversion function returns a double you should check that the result can be represented by a float and cast the value to a float variable. But I would consider to use double as the internal representation.
In addition to Singer's answer:
The commandline should be used mainly by human, not computer. If you really need a table of values, use configuration file. You can always use human readable format for it.