check decimal or point Java - arrays

i am working on a calculator project.
i am using a method to separate the char and numeric values.
but i am getting problem on when i have a decimal value, because result shown 0 when decimal value runs.
here is the code.
List<Double> numbers = new ArrayList<>();
List<Character> operators = new ArrayList<>();
..................
void testing() {
String userInput = "234+234+234";
/* ignore the line above its just for understanding */
/*the above works fine but if we change it to below its dont work.*/
String userInput = "234+2.3+4.2";
/* The both lines above are just for understanding actually i am getting text from edittext*/
String userInput = currentcalc.getText().toString();
for (char c : userInput.toCharArray()) {
if (!Character.isDigit(c)) {
s1 = Double.parseDouble(s2);
numbers.add(s1);
operators.add(c);
handler++;
s2 = "";
s1 = 0;
} else {
s = Character.toString(c);
s2 += s;
}
}
result();
}
result = 0.0
s and s2 are strings and s1 is double. and in my code if c is not a digit it is saving value of operator like +,- etc and else it is saving value of digits and other things. i want to know that why "." is not being save via this code and why result is showing 0.0
the result(); code is here below
void result() {
double total4 = 0;
s1 = Double.parseDouble(s2);
numbers.add(s1);
if (handler < 1) {
total4 = Double.parseDouble(currentcalc.getText().toString());
} else {
int i = 0;
for (i = 0; i < handler; i++) {
switch (operators.get(i)) {
case '/':
total3 = numbers.get(i) / numbers.get(i + 1);
total4 = total3;
numbers.remove(i + 1);
numbers.set(i, total4);
operators.remove(i);
handler--;
i--;
break;
}
}
for (i = 0; i < handler; i++) {
switch (operators.get(i)) {
case '*':
total3 = numbers.get(i) * numbers.get(i + 1);
total4 = total3;
numbers.remove(i + 1);
numbers.set(i, total4);
operators.remove(i);
handler--;
i--;
break;
}
}
for (i = 0; i < handler; i++) {
switch (operators.get(i)) {
case '+':
total3 = numbers.get(i) + numbers.get(i + 1);
total4 = total3;
numbers.remove(i + 1);
numbers.set(i, total4);
operators.remove(i);
break;
case '-':
total3 = numbers.get(i) - numbers.get(i + 1);
total4 = total3;
numbers.remove(i + 1);
numbers.set(i, total4);
operators.remove(i);
break;
}
handler--;
i--;
}
}
et1.setText(Double.toString(total4));
resettext = 1;
}

Following your result() method, total4 is set to 0.0 at the beginning, and no code ever changes it when the "." operator is encountered.
The bug is that you are treating "." as an operator. Have special code in your parsing loop to treat it as part of the number. You need to change the line if (!Character.isDigit(c)) {, and handle the maths logic.

If you are not required to implement any specific algorithm then you can use:
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
Object result = engine.eval("3+4");
Otherwise you may want to look at the following:
Shunting Yard Algorithm

Related

HOW TO MULTIPLY 2 LARGE NUMBERS AS STRINGS(with a previous fanction that adds 2 strings) ? c

verylong multiply_verylong(verylong vl1, verylong vl2)'verylong defines as typedef char* verylong'
{
size_t maxln, minln;
int carry=0, placeSaver=1, i, k ,sum=0,dif,newln,newln2,ln1,ln2;
verylong newNum , maxVl,minVl,tempvl,addvl;
ln1 = strlen(vl1); // 'length of first str'
ln2 = strlen(vl2);'length of second str'
if (ln1 >= ln2)
{
maxln = ln1;
minln = ln2;
maxVl = (verylong)calloc(maxln + 1, sizeof(char));
assert(maxVl);
minVl = (verylong)calloc(minln + 1, sizeof(char));
assert(minVl);
strcpy(maxVl, vl1);
strcpy(minVl, vl2);
dif = maxln - minln;
}
else 'stops debuging here'
{
maxln = ln2;
minln = ln1;
maxVl = (verylong)calloc(maxln + 1, sizeof(char));
assert(maxVl);
minVl = (verylong)calloc(minln + 1, sizeof(char));
assert(minVl);
strcpy(maxVl, vl2);
strcpy(minVl, vl1);
dif = maxln - minln;
}
newln = 2 * maxln + 1; 'maximum length of new required string'
newln2 = newln - 1; 'the index of the new string'
newNum = (verylong)calloc(newln,sizeof(char));
addvl = (verylong)calloc(newln, sizeof(char));
tempvl = (verylong)calloc(newln, sizeof(char));
for (i = minln - 1; i >= 0; i--) ' elementry school multiplication'
{
for (k = maxln - 1; k >= 0; k--)
{
sum = ((minVl[i] - '0')*(maxVl[k] - '0')*placeSaver)+carry;
if (sum >= 10)
carry = sum / 10;
if (k == 0)
newNum[newln2] = '0' + sum;
else
newNum[newln2] = '0' + sum%10;
newln2--;
}
placeSaver*=10;
addvl=add_verylong(newNum,tempvl);'sending the 2 strings to a previous function that adds 2 strings'
strcpy(tempvl, addvl);
}
return addvl;
}
void main()
{
char vl1[80], vl2[80];
printf("enter large number\n");
gets(vl1);
printf("enter large number\n");
gets(vl2);
verylong res = multiply_verylong(vl1, vl2);'saves the string '
printf("%s", res);
free(res);
}
I tried to multiply the first digit of the first number from right with all of the digits from the second number moving forward to the second digit of the first number and then to multiply the placesaver by 10 .
***
the problem is that the code outputs usually nothing and sometimes just inccorect result
***
Your approach is basically right, but there are some mistakes in the implementation.
You allocate space for addvl, but overwrite that pointer later with the return value of add_verylong(). This gives a memory leak. Further memory leaks are produced by not freeing tempvl, maxvl, minvl and newNum.
You forgot to initialize tempvl to the number "0".
We cannot shift the intermediate product by multiplying each digit with the power of ten placeSaver. What we can do is place 0 digits to the right of the product newNum.
You failed to correctly set carry in each loop cycle.
You missed that even the leftmost digits can produce a carry.
This code has the mentioned mistakes corrected:
newNum = calloc(newln, sizeof(char));
// do not allocate space for addvl - it would be lost
tempvl = malloc(newln);
strcpy(tempvl, "0"); // don't forget to initialize tempvl to "0"
for (i = minln - 1; i >= 0; i--) // elementry school multiplication
{
newln2 = newln - 1; // the index of the new string
for (carry = 0, k = maxln - 1; k >= 0; k--) // clear carry before each loop
{
sum = (minVl[i] - '0')*(maxVl[k] - '0') + carry;
carry = sum/10;
newNum[--newln2] = '0' + sum%10;
}
if (carry) newNum[--newln2] = '0' + carry;
addvl = add_verylong(newNum+newln2, tempvl); // number starts at +newln2
free(tempvl); // free obsolete number
tempvl = addvl; // rather than strcpy()
newNum[--newln-1] = '0'; // instead of placeSaver*=10
}
free(maxVl), free(minVl), free(newNum);
return addvl;
It works for the example multiply_verylong("23345", "34565"), but you should do further tests.

How to execute faster than "snprintf(mystr, 22, "{%+0.4f,%+0.4f}", (double)3.14159265, (double) 2.718281828459);" on a 32 bit mcu

I've tried a few things, any it seems that at best I'm 1.5x slower than the printf() family of functions, which boggles my mind a bit. I think what I'm up against in this situation is the addressing of my device is 32bit, and I don't have an FPU. I've tried a couple of "ftoa()" implementations and constrained them to only look for 2 digits on the left of the decimal point, and left myself some breadcrumbs as to what the total length is of a larger overall string that I'm trying to build. At the end of the day, it seems like the nature of an array of 8-bit elements on a 32bit system is leading to a bunch of hidden shift operations, bitwise "OR" and bitwise NAND operations that are just slowing things down ridiculously...
Anyone have any general tips for this situation? (other than a re-architect to an 8.24 fixed point design) I've tried the compiler optimizations from wysiwyg to execution speed focused, nothing seems to beat snprintf.
Here's the fastest one that I had tried:
#if (__DEBUG)
#define DATA_FIFO_SIZE (8)
#else
#define DATA_FIFO_SIZE (1024)
#endif
typedef struct
{
int32_t rval[4];
double cval[4];
uint16_t idx;
uint16_t padding; //#attention the compiler was padding with 2 bytes to align to 32bit
} data_fifo_entry;
const char V_ERR_MSG[7] = "ERROR,\0";
static data_fifo_entry data_fifo[DATA_FIFO_SIZE];
static char embed_text[256];
/****
* float to ASCII, adapted from
* https://stackoverflow.com/questions/2302969/how-to-implement-char-ftoafloat-num-without-sprintf-library-function-i#7097567
*
****/
//#attention the following floating point #defs are linked!!
#define MAX_DIGITS_TO_PRINT_FLOAT (6)
#define MAX_SUPPORTED_PRINTABLE_FLOAT (+999999.99999999999999999999999999)
#define MIN_SUPPORTED_PRINTABLE_FLOAT (-999999.99999999999999999999999999)
#define FLOAT_TEST6 (100000.0)
#define FLOAT_TEST5 (10000.0)
#define FLOAT_TEST4 (1000.0)
#define FLOAT_TEST3 (100.0)
#define FLOAT_TEST2 (10.0)
#define FLOAT_TEST1 (1.0)
static inline int ftoa(char *s, const float f_in, const uint8_t precision)
{
float f_p = 0.0001;
float n = f_in;
int neg = (n < 0.0);
int length = 0;
switch (precision)
{
case (1):
{
f_p = 0.1;
break;
}
case (2):
{
f_p = 0.01;
break;
}
case (3):
{
f_p = 0.001;
break;
}
//case (4) is the default assumption
case (5):
{
f_p = 0.00001;
break;
}
case (6):
{
f_p = 0.000001;
break;
}
default: //already assumed, no assignments here
{
break;
}
} /* switch */
// handle special cases
if (isnan(n))
{
strcpy(s, "nan\0");
length = 4;
}
else if ((isinf(n)) || (n >= MAX_SUPPORTED_PRINTABLE_FLOAT) ||
((-1.0 * n) < MIN_SUPPORTED_PRINTABLE_FLOAT))
{
strcpy(s, "inf\0");
length = 4;
}
else if (n == 0.0)
{
int idx;
s[length++] = '+';
s[length++] = '0';
s[length++] = '.';
for (idx = 0; idx < precision; idx++)
{
s[length++] = '0';
}
s[length++] = '\0';
}
else if (((n > 0.0) && (n < f_p)) || ((n < 0.0) && ((-1.0 * n) < f_p)))
{
int idx;
if (n >= 0.0)
{
s[length++] = '+';
}
else
{
s[length++] = '-';
}
s[length++] = '0';
s[length++] = '.';
for (idx = 1; idx < precision; idx++)
{
s[length++] = '0';
}
s[length++] = '\0';
}
else
{
int digit, m;
if (neg)
{
n = -n;
}
// calculate magnitude
if (n >= FLOAT_TEST6)
{
m = 6;
}
else if (n >= FLOAT_TEST5)
{
m = 5;
}
else if (n >= FLOAT_TEST4)
{
m = 4;
}
else if (n >= FLOAT_TEST3)
{
m = 3;
}
else if (n >= FLOAT_TEST2)
{
m = 2;
}
else if (n >= FLOAT_TEST1)
{
m = 1;
}
else
{
m = 0;
}
if (neg)
{
s[length++] = '-';
}
else
{
s[length++] = '+';
}
// set up for scientific notation
if (m < 1.0)
{
m = 0;
}
// convert the number
while (n > f_p || m >= 0)
{
double weight = pow(10.0, m);
if ((weight > 0) && !isinf(weight))
{
digit = floor(n / weight);
n -= (digit * weight);
s[length++] = '0' + digit;
}
if ((m == 0) && (n > 0))
{
s[length++] = '.';
}
m--;
}
s[length++] = '\0';
}
return (length - 1);
} /* ftoa */
static inline void print2_and_idx(int8_t idx1, int8_t idx2, uint16_t fifo_idx)
{
//#attention 10 characters already in the buffer, idx does NOT start at zero
uint8_t idx = V_PREFIX_LENGTH;
char scratch[16] = {'\0'};
char * p_fifo_id;
if ((idx1 >= 0) && (idx1 < MAX_IDX) && (idx2 >= 0) && (idx2 < MAX_IDX) &&
(fifo_idx >= 0) && (fifo_idx < DATA_FIFO_SIZE))
{
ftoa(scratch, data_fifo[fifo_idx].cval[idx1], 4);
memcpy((void *)&embed_text[idx += 7], (void *)scratch, 7);
embed_text[idx++] = ',';
ftoa(scratch, data_fifo[fifo_idx].cval[idx2], 4);
memcpy((void *)&embed_text[idx += 7], (void *)scratch, 7);
embed_text[idx++] = ',';
//!\todo maybe print the .idx as fixed width, zero pad to 5 digits
p_fifo_id = utoa((char *)&embed_text[idx], (unsigned int)data_fifo[fifo_idx].idx, 10);
idx += strlen(p_fifo_id);
embed_text[idx++] = ',';
}
else
{
memcpy((void *)&embed_text[idx], (void *)V_ERR_MSG, 7);
}
} /* print2_and_idx */
Instead of using *printf() with FP arguments, convert the FP values first into scaled integers.
With still calling snprintf(), yet with integer and simple character arguments, my code was about 20x faster than the baseline.
Your mileage may vary. YMMV.
//baseline
void format2double_1(char *mystr, double pi, double e) {
snprintf(mystr, 22, "{%+0.4f,%+0.4f}", pi, e);
//puts(mystr);
}
void format2double_2(char *mystr, double pi, double e) {
int pi_i = (int) lrint(pi * 10000.0);
int api_i = abs(pi_i);
int e_i = (int) lrint(e * 10000.0);
int ae_i = abs(e_i);
snprintf(mystr, 22, "{%c%d.%04d,%c%d.%04d}", //
"+-"[pi_i < 0], api_i / 10000, api_i % 10000, //
"+-"[e_i < 0], ae_i / 10000, ae_i % 10000);
//puts(mystr);
}
[edit]
For a proper -0.0 text, use "+-"[!!signbit(pi)]
[edit]
Some idea for OP to consider as a ftoa() replacement. Central code is lrint(f_in * fscale[precision]); which rounds and scales. Untested.
#define PRINTABLE_MAGNITUDE_LIMIT 1000000
int ftoa_1(char *s, const float f_in, const uint8_t precision) {
int n;
sprintf(s, "%+.*f%n", precision, f_in, &n);
return n;
}
int ftoa_2(char *s, const float f_in, const uint8_t precision) {
float fscale[] = { 1, 10, 100, 1000, 10000, 100000, 1000000 };
long iscale[] = { 1, 10, 100, 1000, 10000, 100000, 1000000 };
assert(precision > 0 && precision < sizeof fscale / sizeof fscale[0]);
// gross range check
if (f_in > -PRINTABLE_MAGNITUDE_LIMIT && f_in < PRINTABLE_MAGNITUDE_LIMIT) {
long value = lrint(f_in * fscale[precision]);
value = labs(value);
long scale = iscale[precision];
long ipart = value / scale;
long fpart = value % scale;
// fine range check
if (ipart < PRINTABLE_MAGNITUDE_LIMIT) {
int n;
sprintf(s, "%c%ld:%0*ld%n", signbit(f_in) ? '-' : '+', ipart, precision,
fpart, &n);
return n;
}
}
// Out of range values need not be of performance concern for now.
return ftoa_1(s, f_in, precision);
}
[edit]
To convert a positive or 0 integer to a string quickly without the need to shift the buffer or reverse it, see below. It also returns the string length for subsequent string building.
// Convert an unsigned to a decimal string and return its length
size_t utoa_length(char *dest, unsigned u) {
size_t len = 0;
if (u >= 10) {
len = utoa_length(dest, u/10);
dest += len;
}
dest[0] = '0' + u%10;
dest[1] = '\0';
return len + 1;
}
In a similar vein of #chux's answer, if the remaining snprintf is still slow you can go down the rabbit hole of hand-composing strings/hand-rendering integers.
char *fmtp04f(char *buf, char *lim, double d) {
// if there's no space at all don't bother
if(buf==lim) return buf;
// 10 characters in maximum 32 bit integer, one for the dot,
// one for the terminating NUL in debug prints
char b[12];
// current position in the buffer
char *bp = b;
// scale and round
int32_t i = lrint(d * 10000.);
// write sign and fix i sign
// (we do have at least one character available in buf)
if(signbit(d)) {
*buf++='-';
i = -i;
} else {
*buf++='+';
}
// *always* write down the last 4 digits, even if they are zeroes
// (they'll become the 4 digits after the decimal dot)
for(; bp!=b+4; ) {
*bp++ = '0' + i%10;
i/=10;
}
*bp++='.';
// write down the remaining digits, writing at least one
do {
*bp++ = '0' + i%10;
i/=10;
} while(i != 0);
// bp is at the character after the last, step back
--bp;
// data is now into b *in reversed order*;
// reverse-copy it into the user-provided buffer
while(buf!=lim) {
*buf++ = *bp;
// check before decrementing, as a pointer to one-before-first
// is not allowed in C
if(bp == b) break;
--bp;
}
if(buf!=lim) *buf=0; // "regular" case: terminate *after*
else lim[-1]=0; // bad case: truncate
return buf;
}
void doformat(char *buf, char *lim, double a, double b) {
if(buf==lim) return; // cannot do anything
*buf++='{';
if(buf==lim) goto end;
buf = fmtp04f(buf, lim, a);
if(buf==lim) return; // already terminated by fmtp04f
*buf++=',';
if(buf==lim) goto end;
buf = fmtp04f(buf, lim, b);
if(buf==lim) return; // idem
*buf++='}';
if(buf==lim) goto end;
*buf++=0;
end:
lim[-1]=0; // always terminate
}
It passes some random tests, so I'm reasonably confident that it is not too wrong.
For some reason, #chux version on my machine (64 bit Linux, gcc 6.3) is generally 2/3 times faster than the baseline, while my version is usually 10/30 times faster than the baseline. I don't know if this is because my snprintf is particularly good or particularly bad. As said above, YMMV.

Is my pointer bad initialized?

I am struggling with an error while debugging my application, I have been able to point out that the error seems to happen in the call to the function adc_gain_enum_to_real_gain(),however I don't see why it goes wrong, I suspect is related to passing/reading the pointer &adc_gain. Any hints?
Thanks in advance!
void saadc_handler_interrupt(nrf_drv_saadc_evt_t const * const p_event)
{
uint32_t err_code;
uint16_t voltage;
nrf_saadc_value_t adc_result;
uint16_t tmp_voltage;
float adc_gain;
if (p_event->type == NRF_DRV_SAADC_EVT_CALIBRATEDONE)
{
m_adc_cal_in_progress = false;
}
else if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
{
adc_result = p_event->data.done.p_buffer[0];
err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, 1);
APP_ERROR_CHECK(err_code);
err_code = adc_gain_enum_to_real_gain(ADC_GAIN, &adc_gain); //<===HERE!!
APP_ERROR_CHECK(err_code);
float tmp = adc_result / (( (1/6) / ADC_REFERENCE_VOLTAGE) * pow(2, ADC_RESOLUTION_BITS));
tmp_voltage = (uint16_t) ((tmp / m_battery_divider_factor) * 1000);
voltage = ( (tmp_voltage + 5) / 10) * 10; // Round the value.
NRF_LOG_INFO("Read value from saadc %d\nV",voltage);
batt_event_handler_adc(voltage);
}
//nrf_drv_saadc_uninit();
}
Such a function is
uint32_t adc_gain_enum_to_real_gain(nrf_saadc_gain_t gain_reg, float * const real_val)
{
switch(gain_reg)
{
case NRF_SAADC_GAIN1_6: *real_val = 1 / (float)6;
break;
case NRF_SAADC_GAIN1_5: *real_val = 1 / (float)5;
break;
case NRF_SAADC_GAIN1_4: *real_val = 1 / (float)4;
break;
case NRF_SAADC_GAIN1_3: *real_val = 1 / (float)3;
break;
case NRF_SAADC_GAIN1_2: *real_val = 1 / (float)2;
break;
case NRF_SAADC_GAIN1: *real_val = 1;
break;
case NRF_SAADC_GAIN2: *real_val = 2;
break;
case NRF_SAADC_GAIN4: *real_val = 3;
break;
default: return M_BATT_STATUS_CODE_INVALID_PARAM;
};
return M_BATT_STATUS_CODE_SUCCESS;
}
Here
float tmp = adc_result / (( (1/6) / ADC_REFERENCE_VOLTAGE) * pow(2, ADC_RESOLUTION_BITS));
(1/6) will always evaluate to 0. It's an integer division!
So the whole expression (( (1/6) / ADC_REFERENCE_VOLTAGE) * pow(2, ADC_RESOLUTION_BITS)) results in 0. (note: floating point here), which in turn provokes a division by zero here adc_result / ....
To fix this either do
(1./6)
or
(1/6.)
or
((float) 1/6)
or
(1 /(float) 6)
or any combination of the above.
Unrelated but another cause of trouble related to integer division as well is here:
(tmp_voltage + 5) / 10
Fix as above.

Counting vowels in text without arrays (C)

i have to write a program that counts all vowels in a text & gives out the percentage of every vowel for the whole text.
For whatever reason we are not allowed to use arrays, but instead should do it with getchar().
#include <stdio.h>
#include <ctype.h>
int main() {
int current;
int cntAll = 0;
int cntA = 0, cntE = 0, cntI = 0, cntO = 0, cntU = 0;
int pA = 0, pE = 0, pI = 0, pO = 0, pU = 0;
printf("Enter Text: ");
while ((current = getchar()) != EOF){
if (isspace(current)) continue; // check for whitespace, if whitespace continue
else {
switch (current) { // check for vowel & increase vowelcount
case 'a':
cntA += 1;
case 'A':
cntA += 1;
case 'e':
cntE += 1;
case 'E':
cntE += 1;
case 'i':
cntI += 1;
case 'I':
cntI += 1;
case 'o':
cntO += 1;
case 'O':
cntO += 1;
case 'u':
cntU += 1;
case 'U':
cntU += 1;
}
}
cntAll++;
}
pA = (cntA / cntAll) * 100;
pE = (cntE / cntAll) * 100;
pI = (cntI / cntAll) * 100;
pO = (cntO / cntAll) * 100;
pU = (cntU / cntAll) * 100;
printf("\nLetters: %d\nPercentage A: %d\nPercentage E: %d\nPercentage I: %d\nPercentage O: %d\nPercentage U: %d\n",cntAll,pA,pE,pI,pO,pU);
system("PAUSE");
return 0;
}
Increasing the cntAll value works without problems, but it doesn't count the individual vowels for whatever reason.
Would appreciate any help!
Edited:
#include <stdio.h>
#include <ctype.h>
int main() {
int current;
int cntAll = 0;
int cntA = 0, cntE = 0, cntI = 0, cntO = 0, cntU = 0;
double pA = 0, pE = 0, pI = 0, pO = 0, pU = 0;
printf("Enter Text: ");
while ((current = getchar()) != EOF){
if (isspace(current)) continue;
else {
switch (current) {
case 'a':case 'A':
cntA += 1;
break;
case 'e':case 'E':
cntE += 1;
break;
case 'i':case 'I':
cntI += 1;
break;
case 'o':case 'O':
cntO += 1;
break;
case 'u':case 'U':
cntU += 1;
break;
}
}
cntAll++;
}
pA = 100.0 * cntA / cntAll;
pE = 100.0 * cntE / cntAll;
pI = 100.0 * cntI / cntAll;
pO = 100.0 * cntO / cntAll;
pU = 100.0 * cntU / cntAll;
printf("\nLetters: %d\nPercentage A: %.2lf\nPercentage E: %.2lf\nPercentage I: %.2lf\nPercentage O: %.2lf\nPercentage U: %.2lf\n",cntAll,pA,pE,pI,pO,pU);
system("PAUSE");
return 0;
}
cheers
You need to insert break statements between the cases.
Otherwise the program will execute all the statements below the one first entered. Actually this is a good feature. It allows you to consider multiple labels at the same time. Putting this together you get:
switch (current){
case 'a': case 'A':
cntA += 1;
break; // Don't follow through to the other cases.
case 'b': case 'B': /*etc*/
After this, note that (cntA / cntAll) * 100; will evaluate the expression in parentheses in integer arithmetic, which will truncate it to 0 in most cases. The fix is to write it as
100 * cntA / cntAll;
This will still truncate to an integer. If that's not tolerable then consider using the floating point expression 100.0 * cntA / cntAll and change your printf formatters accordingly. Using floating point is arguably better anyway as it obviates the potential for overflow when evaluating 100 * cntA.
case labels falls through to the next one below it without a break.
So if you read an 'a' then all the cases in your switch will be executed.
You need something like
switch (current) { // check for vowel & increase vowelcount
case 'a':
cntA += 1;
break; // <-- Note break here
...
First thing i notice is that you are missing break on every switch case. This will lead to wrong behaviour.
Second thing:
pA = (cntA / cntAll) * 100;
will calculate cntS/cntAll first which is <0. This value will be interpreted as integer so you always have 0*100 which is 0. You can rewrite it as
pA = (cntA * 100 ) / cntAll;
In that case you don't have to cast to float to get the right result. Note that for large cntA you may overflow.

generating random numbers without repeating with an exception AS3

I have seen this question for other languages but not for AS3... and I'm having a hard time understanding it...
I need to generate 3 numbers, randomly, from 0 to 2, but they cannot repeat (as in 000, 001, 222, 212 etc) and they cannot be in the correct order (0,1,2)...
Im using
for (var u: int = 0; u < 3; u++)
{
mcCor = new CorDaCarta();
mcCor.x = larguraTrio + (mcCor.width + 5) * (u % 3);
mcCor.y = alturaTrio + (mcCor.height + 5) * (Math.floor(u / 3));
mcCor.gotoAndStop((Math.random() * (2 - u + 1) + u) | 0); // random w/ repeats
//mcCor.gotoAndStop(Math.floor(Math.random() * (2 - u + 1) + u)); // random w/ repeats
//mcCor.gotoAndStop((Math.random() * 3) | 0); // crap....
//mcCor.gotoAndStop(Math.round(Math.random()*u)); // 1,1,1
//mcCor.gotoAndStop(u + 1); // 1,2,3
mcCor.buttonMode = true;
mcCor.addEventListener(MouseEvent.CLICK, cliquetrio);
mcExplic.addChild(mcCor);
trio.push(mcCor);
}
those are the codes i've been trying.... best one so far is the active one (without the //), but it still gives me duplicates (as 1,1,1) and still has a small chance to come 0,1,2....
BTW, what I want is to mcCor to gotoAndStop on frames 1, 2 or 3....without repeating, so THE USER can put it on the right order (1,2,3 or (u= 0,1,2), thats why I add + 1 sometimes there)
any thoughts?? =)
I've found that one way to ensure random, unique numbers is to store the possible numbers in an array, and then sort them using a "random" sort:
// store the numbers 0, 1, 2 in an array
var sortedNumbers:Array = [];
for(var i:int = 0; i < 3; i++)
{
sortedNumbers.push(i);
}
var unsortedNumbers:Array = sortedNumbers.slice(); // make a copy of the sorted numbers
trace(sortedNumbers); // 0,1,2
trace(unsortedNumbers); // 0,1,2
// randomly sort array until it no longer matches the sorted array
while(sortedNumbers.join() == unsortedNumbers.join())
{
unsortedNumbers.sort(function (a:int, b:int):int { return Math.random() > .5 ? -1 : 1; });
}
trace(unsortedNumbers); // [1,0,2], [2,1,0], [0,1,2], etc
for (var u: int = 0; u < 3; u++)
{
mcCor = new CorDaCarta();
mcCor.x = larguraTrio + (mcCor.width + 5) * (u % 3);
mcCor.y = alturaTrio + (mcCor.height + 5) * (Math.floor(u / 3));
// grab the corresponding value from the unsorted array
mcCor.gotoAndStop(unsortedNumbers[u] + 1);
mcCor.buttonMode = true;
mcCor.addEventListener(MouseEvent.CLICK, cliquetrio);
mcExplic.addChild(mcCor);
trio.push(mcCor);
}
Marcela is right. Approach with an Array is widely used for such task. Of course, you will need to check 0, 1, 2 sequence and this will be ugly, but in common code to get the random sequence of integers can look like this:
function getRandomSequence(min:int, max:int):Array
{
if (min > max) throw new Error("Max value should be greater than Min value!");
if (min == max) return [min];
var values:Array = [];
for (var i:int = min; i <= max; i++) values.push(i);
var result:Array = [];
while (values.length > 0) result = result.concat(values.splice(Math.floor(Math.random() * values.length), 1));
return result;
}
for (var i:uint = 0; i < 10; i++)
{
trace(getRandomSequence(1, 10));
}
You will get something like that:
2,9,3,8,10,6,5,1,4,7
6,1,2,4,8,9,5,10,7,3
3,9,10,6,8,2,5,4,1,7
7,6,1,4,3,8,9,2,10,5
4,6,7,1,3,2,9,10,8,5
3,10,5,9,1,7,2,4,8,6
1,7,9,6,10,3,4,5,2,8
4,10,8,9,3,2,6,1,7,5
1,7,8,9,10,6,4,3,2,5
7,5,4,2,8,6,10,3,9,1
I created this for you. It is working but it can be optimized...
Hope is good for you.
var arr : Array = [];
var r : int;
for (var i: int = 0; i < 3; i++){
r=rand(0,2);
if(i == 1){
if(arr[0] == r){
i--;
continue;
}
if(arr[0] == 0){
if(r==1){
i--;
continue;
}
}
}else if(i==2){
if(arr[0] == r || arr[1] == r){
i--;
continue;
}
}
arr[i] = r;
}
trace(arr);
for(var i=0;i<3;i++){
mcCor = new CorDaCarta();
mcCor.x = larguraTrio + (mcCor.width + 5) * (i % 3);
mcCor.y = alturaTrio + (mcCor.height + 5) * (Math.floor(i / 3));
mcCor.gotoAndStop(arr[i]);
mcCor.buttonMode = true;
mcCor.addEventListener(MouseEvent.CLICK, cliquetrio);
mcExplic.addChild(mcCor);
trio.push(mcCor);
}
function rand(min:int, max:int):int {
return Math.round(Math.random() * (max - min) + min);
}
try this...

Resources