Example usage for java.lang Math floor

List of usage examples for java.lang Math floor

Introduction

In this page you can find the example usage for java.lang Math floor.

Prototype

public static double floor(double a) 

Source Link

Document

Returns the largest (closest to positive infinity) double value that is less than or equal to the argument and is equal to a mathematical integer.

Usage

From source file:change_point_detection.CpdDP.java

public int/*estimated change point*/ detectChange() throws Exception {
    int estimatedChangePoint = -1;
    int N = this.dynamicWindow.size();
    this.cushion = Math.max(100, (int) Math.floor(Math.pow(N, gamma)));
    //mean conf. should not fall below 0.3
    double preChangeMean, postChangeMean, wholeMean;
    wholeMean = calculateMean(0, N - 1);
    if ((N > (2 * this.cushion) && wholeMean <= 0.3) || this.dynamicWindow.size() > this.dim)
        return N - 1;
    double threshold = -Math.log(this.sensitivity);
    double w = 0;
    int kAtMaxW = -1;
    for (int k = this.cushion; k <= N - this.cushion; k++) {
        double skn = 0;
        int prevN = this.trackN[k];
        preChangeMean = prevN == -1 ? calculateMean(0, k - 1)
                : this.cusumElementArr[prevN][k].getPreChangeMean();
        postChangeMean = calculateMean(k, N - 1);
        if (postChangeMean <= (1 - this.secAlgMarSlack) * preChangeMean) {//signal from secondary
            if (prevN == -1) {
                //calculate from scratch
                /* estimate pre and post change parameters */
                double alphaPreChange = calcBetaDistAlpha(0, k - 1, preChangeMean);
                double betaPreChange = calculateBetaDistBeta(alphaPreChange, 0, k - 1, preChangeMean);
                double alphaPostChange = calcBetaDistAlpha(k, N - 1, postChangeMean);
                double betaPostChange = calculateBetaDistBeta(alphaPostChange, k, N - 1, postChangeMean);
                BetaDistributionImpl preBetaDist = new BetaDistributionImpl(alphaPreChange, betaPreChange);
                BetaDistributionImpl postBetaDist = new BetaDistributionImpl(alphaPostChange, betaPostChange);
                for (int i = k; i < N; i++) {
                    try {
                        skn += Math.log(postBetaDist.density(this.dynamicWindow.get(i).doubleValue())
                                / preBetaDist.density(this.dynamicWindow.get(i).doubleValue()));
                    } catch (Exception e) {
                        e.printStackTrace();
                        System.out.println("continuing...");
                        skn = 0;//  w  ww . ja v  a2s.  c o m
                        break;
                    }
                }
                this.cusumElementArr[N - 1][k] = new CusumElement(preBetaDist, postBetaDist, preChangeMean,
                        skn);
            } else {//warning and calculate recursively
                double alphaPostChange2 = calcBetaDistAlpha(k, N - 1, postChangeMean);
                double betaPostChange2 = calculateBetaDistBeta(alphaPostChange2, k, N - 1, postChangeMean);
                BetaDistributionImpl postBetaDist2 = new BetaDistributionImpl(alphaPostChange2,
                        betaPostChange2);
                skn += this.cusumElementArr[prevN][k].getCusumScore();
                for (int i = prevN + 1; i < N; i++) {
                    try {
                        skn += Math.log(postBetaDist2.density(this.dynamicWindow.get(i).doubleValue())
                                / this.cusumElementArr[prevN][k].getPreChangeDist()
                                        .density(this.dynamicWindow.get(i).doubleValue()));
                    } catch (Exception e) {
                        e.printStackTrace();
                        System.out.println("continuing...");
                        skn = 0;
                        break;
                    }
                }
                this.cusumElementArr[N - 1][k] = new CusumElement(
                        this.cusumElementArr[prevN][k].getPreChangeDist(), postBetaDist2, preChangeMean, skn);
            }
            this.trackN[k] = N - 1;
        }
        if (skn > w) {
            w = skn;
            kAtMaxW = k;
        }
    }
    if (w >= threshold && kAtMaxW != -1) {
        System.out.println("\nChangePoint Found!");
        estimatedChangePoint = kAtMaxW;
        System.out.println("Estimated change point is " + estimatedChangePoint + ", detected at point: " + N);
    }
    //force change point if confidence falls down terribly
    if (estimatedChangePoint == -1 && N >= 100 && wholeMean < 0.3)
        estimatedChangePoint = N - 1;
    return estimatedChangePoint;
}

From source file:info.debatty.java.datasets.sift.Matrix.java

public static int[] floor(double[] a) {
    int[] b = new int[a.length];
    for (int i = 0; i < a.length; i++) {
        b[i] = (int) Math.floor(a[i]);
    }//from ww w . j  a v a  2  s.c  o m
    return b;
}

From source file:com.miz.mizuu.fragments.CoverSearchFragment.java

@Override
public void onViewCreated(View v, Bundle savedInstanceState) {
    super.onViewCreated(v, savedInstanceState);

    mProgressBar = (ProgressBar) v.findViewById(R.id.progress);
    if (mImageUrls.size() > 0)
        mProgressBar.setVisibility(View.GONE); // Hack to remove the ProgressBar on orientation change

    mGridView = (GridView) v.findViewById(R.id.gridView);

    mAdapter = new ImageAdapter(getActivity());
    mGridView.setAdapter(mAdapter);//from   w  w  w . ja  va  2 s  .co  m

    // Calculate the total column width to set item heights by factor 1.5
    mGridView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            final int numColumns = (int) Math
                    .floor(mGridView.getWidth() / (mImageThumbSize + mImageThumbSpacing));
            if (numColumns > 0) {
                mGridView.setNumColumns(numColumns);
            }
        }
    });
    mGridView.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            // Create the download Service
            Intent downloadService = new Intent(getActivity(), DownloadImageService.class);
            downloadService.putExtra(DownloadImageService.CONTENT_ID, mTmdbId);
            downloadService.putExtra(DownloadImageService.IMAGE_URL, mImageUrls.get(arg2));
            downloadService.putExtra(DownloadImageService.IMAGE_TYPE,
                    DownloadImageService.IMAGE_TYPE_MOVIE_COVER);
            getActivity().startService(downloadService);

            // End the browser Activity
            getActivity().finish();
        }
    });

    mJson = getArguments().getString("json");
    loadJson(getArguments().getString("baseUrl"));
}

From source file:berlin.iconn.persistence.InOutOperations.java

public static int[] loadSiftFlowLabel(int imageSize, File file) throws FileNotFoundException, IOException {
    int n = 256;// w  w  w .  j  av a 2  s  . c om
    int[] result = new int[n * n];
    try (BufferedReader br = new BufferedReader(new FileReader(file))) {
        for (int j = 0; j < 5; ++j) {
            br.readLine();
        }
        String line;
        int lineCount = 0;
        while ((line = br.readLine()) != null) {
            line = line.trim();
            if (!line.equals("")) {
                result[lineCount] = new Integer(line);
            }
            ++lineCount;
        }
    }

    // transpose
    int index1, index2, tempVar;
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            index1 = i * n + j;
            index2 = j * n + i;
            tempVar = result[index1];
            result[index1] = result[index2];
            result[index2] = tempVar;
        }
    }

    // resize
    int[] resizedResult = new int[imageSize * imageSize];
    double ratio = 256 / (double) imageSize;
    for (int i = 0; i < imageSize; i++) {
        for (int j = 0; j < imageSize; j++) {
            int index = (int) (Math.floor(i * ratio) * 256 + Math.floor(j * ratio));
            resizedResult[i * imageSize + j] = result[index];
        }
    }

    return resizedResult;
}

From source file:gr.iti.mklab.reveal.forensics.maps.dq.DQExtractor.java

public void detectDQDiscontinuities() {

    int imWidth = dcts.length;
    int imHeight = dcts[0].length;

    int[] p_h_avg = new int[maxCoeffs];
    int[] p_h_fft = new int[maxCoeffs];
    int[] p_final = new int[maxCoeffs];

    double[][] pTampered = new double[maxCoeffs][];
    double[][] pUntampered = new double[maxCoeffs][];

    for (int coeffIndex = 0; coeffIndex < maxCoeffs; coeffIndex++) {

        int coe = coeff[coeffIndex];
        int startY = coe % 8 - 1;
        if (startY == -1) {
            startY = 8;//from  w ww  .j av a  2s . c  o m
        }
        int startX = (int) Math.floor((coe - 1) / 8);

        List<Integer> selectedCoeffs = new ArrayList<Integer>();
        for (int ii = startX; ii < imWidth; ii += 8) {
            for (int jj = startY; jj < imHeight; jj += 8) {
                selectedCoeffs.add(dcts[ii][jj]);
            }
        }

        int minCoeffValue = Collections.min(selectedCoeffs);
        int maxCoeffValue = Collections.max(selectedCoeffs);
        int s_0;
        Double[] coeffHist = new Double[0];
        if (maxCoeffValue - minCoeffValue > 0) {
            //will be a power of 2 to allow for fft (zero padded)
            int trueHistRange = maxCoeffValue - minCoeffValue + 1;
            //int histLength = trueHistRange;
            int histLength = (int) Math.pow(2, Math.ceil(Math.log(trueHistRange) / Math.log(2)));

            coeffHist = new Double[histLength];

            for (int ii = 0; ii < coeffHist.length; ii++) {
                coeffHist[ii] = 0.0;
            }

            for (Integer selectedCoeff : selectedCoeffs) {
                coeffHist[selectedCoeff - minCoeffValue] += 1;
            }

            List<Double> coeffHistList = Arrays.asList(coeffHist);
            s_0 = coeffHistList.indexOf(Collections.max(coeffHistList));

            List<Double> h = new ArrayList<>();
            DescriptiveStatistics vals;
            for (int coeffInd = 1; coeffInd < coeffHistList.size(); coeffInd++) {
                vals = new DescriptiveStatistics();
                for (int leapInd = s_0; leapInd < coeffHistList.size(); leapInd += coeffInd) {
                    vals.addValue(coeffHistList.get(leapInd));
                }
                for (int leapInd = s_0 - coeffInd; leapInd >= 0; leapInd -= coeffInd) {
                    vals.addValue(coeffHistList.get(leapInd));
                }
                h.add(vals.getMean());
            }
            p_h_avg[coeffIndex] = (h.indexOf(Collections.max(h)));

            FastFourierTransformer fastFourierTransformer = new FastFourierTransformer(
                    DftNormalization.STANDARD);
            Complex[] fft = fastFourierTransformer.transform(ArrayUtils.toPrimitive(coeffHist),
                    TransformType.FORWARD);

            double[] power = new double[fft.length];
            for (int ii = 0; ii < power.length; ii++) {
                power[ii] = fft[ii].abs();
            }

            //Find first local minimum, to bypass DC peak
            double DC = power[0];
            int FreqValley = 1;
            while (FreqValley < power.length - 1 & power[FreqValley] >= power[FreqValley + 1]) {
                FreqValley++;
            }

            int maxFFTInd = 0;
            double maxFFTVal = 0;
            double minFFTVal = Double.MAX_VALUE;
            for (int ii = FreqValley; ii < power.length / 2; ii++) {
                if (power[ii] > maxFFTVal) {
                    maxFFTInd = ii;
                    maxFFTVal = power[ii];
                }
                if (power[ii] < minFFTVal) {
                    minFFTVal = power[ii];
                }
            }
            if (maxFFTInd == 0 | maxFFTVal < (DC / 5) | minFFTVal / maxFFTVal > 0.9) {
                p_h_fft[coeffIndex] = 1;
            } else {
                p_h_fft[coeffIndex] = Math.round(coeffHist.length / maxFFTInd);
            }

        } else {
            p_h_avg[coeffIndex] = 1;
            p_h_fft[coeffIndex] = 1;
            s_0 = 0;
        }
        if (p_h_avg[coeffIndex] < p_h_fft[coeffIndex]) {
            p_final[coeffIndex] = p_h_avg[coeffIndex];
        } else {
            p_final[coeffIndex] = p_h_fft[coeffIndex];
        }

        pTampered[coeffIndex] = new double[selectedCoeffs.size()];
        pUntampered[coeffIndex] = new double[selectedCoeffs.size()];
        int[] adjustedCoeffs = new int[selectedCoeffs.size()];
        int[] period_start = new int[selectedCoeffs.size()];
        int[] period;
        int[] num = new int[selectedCoeffs.size()];
        int[] denom = new int[selectedCoeffs.size()];
        double[] P_u = new double[selectedCoeffs.size()];
        double[] P_t = new double[selectedCoeffs.size()];

        if (p_final[coeffIndex] != 1) {
            for (int ii = 0; ii < adjustedCoeffs.length; ii++) {
                adjustedCoeffs[ii] = selectedCoeffs.get(ii) - minCoeffValue;
                period_start[ii] = adjustedCoeffs[ii] - rem(adjustedCoeffs[ii] - s_0, p_final[coeffIndex]);
            }
            for (int kk = 0; kk < selectedCoeffs.size(); kk++) {
                if (period_start[kk] > s_0) {
                    period = new int[p_final[coeffIndex]];
                    for (int ii = 0; ii < p_final[coeffIndex]; ii++) {
                        period[ii] = period_start[kk] + ii;
                        if (period[ii] >= coeffHist.length) {
                            period[ii] = period[ii] - p_final[coeffIndex];
                        }
                    }
                    num[kk] = (int) coeffHist[adjustedCoeffs[kk]].doubleValue();
                    denom[kk] = 0;
                    for (int ll = 0; ll < period.length; ll++) {
                        denom[kk] = denom[kk] + (int) coeffHist[period[ll]].doubleValue();
                    }
                } else {
                    period = new int[p_final[coeffIndex]];
                    for (int ii = 0; ii < p_final[coeffIndex]; ii++) {
                        period[ii] = period_start[kk] - ii;
                        if (period_start[kk] - p_final[coeffIndex] + 1 <= 0) {
                            if (period[ii] <= 0) {
                                period[ii] = period[ii] + p_final[coeffIndex];
                            }
                        }
                    }
                    num[kk] = (int) coeffHist[adjustedCoeffs[kk]].doubleValue();
                    denom[kk] = 0;
                    for (int ll = 0; ll < period.length; ll++) {
                        denom[kk] = denom[kk] + (int) coeffHist[period[ll]].doubleValue();
                    }
                }

                P_u[kk] = ((double) num[kk] / denom[kk]);
                P_t[kk] = (1.0 / p_final[coeffIndex]);
                if (P_u[kk] + P_t[kk] != 0) {
                    pTampered[coeffIndex][kk] = P_t[kk] / (P_u[kk] + P_t[kk]);
                    pUntampered[coeffIndex][kk] = P_u[kk] / (P_u[kk] + P_t[kk]);

                } else {
                    pTampered[coeffIndex][kk] = 0.5;
                    pUntampered[coeffIndex][kk] = 0.5;
                }
            }

        } else {
            for (int kk = 0; kk < selectedCoeffs.size(); kk++) {
                pTampered[coeffIndex][kk] = 0.5;
                pUntampered[coeffIndex][kk] = 0.5;
            }
        }

    }
    double[] pTamperedOverall = new double[pTampered[0].length];
    double pTamperedProd;
    double pUntamperedProd;

    for (int locationIndex = 0; locationIndex < pTampered[0].length; locationIndex++) {
        pTamperedProd = 1;
        pUntamperedProd = 1;
        for (int coeffIndex = 0; coeffIndex < pTampered.length; coeffIndex++) {
            pTamperedProd = pTamperedProd * pTampered[coeffIndex][locationIndex];
            pUntamperedProd = pUntamperedProd * pUntampered[coeffIndex][locationIndex];
        }
        if (pTamperedProd + pUntamperedProd != 0) {
            pTamperedOverall[locationIndex] = pTamperedProd / (pTamperedProd + pUntamperedProd);
        } else {
            pTamperedOverall[locationIndex] = 0;
        }
    }

    int blocksH = imWidth / 8;
    int blocksV = imHeight / 8;
    double[][] outputMap = new double[blocksV][blocksH];
    for (int kk = 0; kk < pTamperedOverall.length; kk++) {
        outputMap[kk % blocksV][(int) Math.floor(kk / blocksV)] = pTamperedOverall[kk];
        if (pTamperedOverall[kk] > maxProbValue) {
            maxProbValue = pTamperedOverall[kk];
        }
        if (pTamperedOverall[kk] < minProbValue) {
            minProbValue = pTamperedOverall[kk];
        }
    }
    probabilityMap = outputMap;
    BufferedImage outputIm = visualizeWithJet(outputMap);
    // output
    displaySurface = outputIm;
}

From source file:fiji.plugin.trackmate.action.brownianmotion.WalkerMethodEstimator.java

/**
 * //from   w w  w. ja v  a2s .  c  om
 * @param data Containes the mean squared displacement and the Tracklength for each track. data[i][0] = MSD data[i][1] = Tracklength
 * @param temp Temperature of the suspension in kelvin
 * @param visk Viscosity of the suspension
 * @param framerate Framerate in hertz
 * @param maxdiameter The maximum diameter for the estimation
 */
public WalkerMethodEstimator(double[][] data, double temp, double visk, double framerate, int maxdiameter) {

    this.data = data;
    this.temp = temp;
    this.visk = visk;
    this.frameduration = 1 / framerate;

    minTrackLength = Integer.MAX_VALUE;
    maxTrackLength = Integer.MIN_VALUE;
    //msdMin = Double.MAX_VALUE;
    msdMax = Double.MIN_VALUE;
    //double convFact = Math.pow(10, -10);

    for (int i = 0; i < data.length; i++) {
        //10^-10 cm^2 -> cm^2
        //this.data[i][0] = this.data[i][0]*convFact; //- 4*17.562862475*17.562862475*Math.pow(10, -7)*Math.pow(10, -7); 
        if (data[i][0] > msdMax) {
            msdMax = data[i][0];
        }
        if (this.data[i][1] > maxTrackLength) {
            maxTrackLength = (int) this.data[i][1];
        }
        if (this.data[i][1] < minTrackLength) {
            minTrackLength = (int) this.data[i][1];
        }
        //IJ.log("MSD " + this.data[i][0]);
    }

    logMapK = new double[maxTrackLength + 1];
    logMapGammaK = new double[maxTrackLength + 1];
    java.util.Arrays.fill(logMapK, Double.NaN);
    java.util.Arrays.fill(logMapGammaK, Double.NaN);
    maxRadiusInNm = maxdiameter / 2.0;

    binNumber = (int) (maxRadiusInNm / binSizeInnm);
    histBinNumber = (int) Math.ceil(Math.sqrt(data.length));
    deltaB = msdMax / histBinNumber;

    histogramMSD = new double[histBinNumber];
    java.util.Arrays.fill(histogramMSD, 0);
    Nk = new int[maxTrackLength + 1];
    java.util.Arrays.fill(Nk, 0);
    for (int i = 0; i < data.length; i++) {
        int index = (int) this.data[i][1];
        Nk[index]++;

        int index2 = (int) Math.floor(data[i][0] / deltaB - 0.001);

        histogramMSD[index2]++;
    }
}

From source file:gov.nih.nci.calims2.business.inventory.container.CoordinateHelper.java

private static int getMaximumLength(LayoutLabelType labelType, int maximum) {
    if (labelType == LayoutLabelType.DIGITS) {
        int length = (int) Math.floor(Math.log(maximum) / Math.log(DIGIT_BASE)) + 1;
        return (length > 1) ? length : 2;
    }//from w  w w.  j av a 2  s  .  c  o  m
    return (int) Math.floor(Math.log(maximum) / Math.log(LETTER_BASE)) + 1;
}

From source file:edu.stanford.cfuller.imageanalysistools.filter.GradientFilter.java

/**
 * Applies the GradientFilter to the specified Image.
 * @param im    The Image that will be replaced by its gradient.
 */// w ww .j a v a2 s  .  c om
@Override
public void apply(WritableImage im) {

    final int kernelSize = 3;
    int halfKernelSize = (kernelSize - 1) / 2;

    RealMatrix kernel1 = new Array2DRowRealMatrix(kernelSize, kernelSize);

    kernel1.setEntry(0, 0, 1);
    kernel1.setEntry(1, 0, 0);
    kernel1.setEntry(2, 0, -1);
    kernel1.setEntry(0, 1, 1);
    kernel1.setEntry(1, 1, 0);
    kernel1.setEntry(2, 1, -1);
    kernel1.setEntry(0, 2, 1);
    kernel1.setEntry(1, 2, 0);
    kernel1.setEntry(2, 2, -1);

    RealMatrix kernel2 = new Array2DRowRealMatrix(kernelSize, kernelSize);

    kernel2.setEntry(0, 0, -1);
    kernel2.setEntry(1, 0, -1);
    kernel2.setEntry(2, 0, -1);
    kernel2.setEntry(0, 1, 0);
    kernel2.setEntry(1, 1, 0);
    kernel2.setEntry(2, 1, 0);
    kernel2.setEntry(0, 2, 1);
    kernel2.setEntry(1, 2, 1);
    kernel2.setEntry(2, 2, 1);

    Image copy = ImageFactory.create(im);

    ImageCoordinate ic = ImageCoordinate.createCoordXYZCT(0, 0, 0, 0, 0);

    for (ImageCoordinate i : im) {

        double outputVal = 0;
        double output1 = 0;
        double output2 = 0;

        if (i.get(ImageCoordinate.X) == 0 || i.get(ImageCoordinate.Y) == 0
                || i.get(ImageCoordinate.X) == copy.getDimensionSizes().get(ImageCoordinate.X) - 1
                || i.get(ImageCoordinate.Y) == copy.getDimensionSizes().get(ImageCoordinate.Y) - 1) {
            outputVal = 0;
        } else {
            for (int p = -1 * halfKernelSize; p < halfKernelSize + 1; p++) {
                for (int q = -1 * halfKernelSize; q < halfKernelSize + 1; q++) {
                    ic.set(ImageCoordinate.X, i.get(ImageCoordinate.X) + p);
                    ic.set(ImageCoordinate.Y, i.get(ImageCoordinate.Y) + q);
                    output1 += kernel1.getEntry(p + halfKernelSize, q + halfKernelSize) * copy.getValue(ic);
                    output2 += kernel2.getEntry(p + halfKernelSize, q + halfKernelSize) * copy.getValue(ic);
                }
            }

            outputVal = FastMath.hypot(output1, output2);
        }

        im.setValue(i, (float) Math.floor(outputVal));

    }

    ic.recycle();

}

From source file:com.miz.mizuu.fragments.CollectionCoverSearchFragment.java

@Override
public void onViewCreated(View v, Bundle savedInstanceState) {
    super.onViewCreated(v, savedInstanceState);

    mProgressBar = (ProgressBar) v.findViewById(R.id.progress);
    if (mImageUrls.size() > 0)
        mProgressBar.setVisibility(View.GONE); // Hack to remove the ProgressBar on orientation change

    mGridView = (GridView) v.findViewById(R.id.gridView);

    mAdapter = new ImageAdapter(getActivity());
    mGridView.setAdapter(mAdapter);//w w  w  .j a  va  2  s. c  o  m

    // Calculate the total column width to set item heights by factor 1.5
    mGridView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            final int numColumns = (int) Math
                    .floor(mGridView.getWidth() / (mImageThumbSize + mImageThumbSpacing));
            if (numColumns > 0) {
                mGridView.setNumColumns(numColumns);
            }
        }
    });
    mGridView.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            // Create the download Service
            Intent downloadService = new Intent(getActivity(), DownloadImageService.class);
            downloadService.putExtra(DownloadImageService.CONTENT_ID, mCollectionId);
            downloadService.putExtra(DownloadImageService.IMAGE_URL, mImageUrls.get(arg2));
            downloadService.putExtra(DownloadImageService.IMAGE_TYPE,
                    DownloadImageService.IMAGE_TYPE_MOVIE_COVER);
            getActivity().startService(downloadService);

            // End the browser Activity
            getActivity().finish();
        }
    });

    mJson = getArguments().getString("json");
    loadJson(getArguments().getString("baseUrl"));
}

From source file:HSSFDateUtil.java

/**
 * Given an Excel date with either 1900 or 1904 date windowing, converts it to
 * a java.util.Date./*  w ww.ja  v  a2 s.  c  o  m*/
 * 
 * NOTE: If the default <code>TimeZone</code> in Java uses Daylight Saving
 * Time then the conversion back to an Excel date may not give the same value,
 * that is the comparison <CODE>excelDate ==
 * getExcelDate(getJavaDate(excelDate,false))</CODE> is not always true. For
 * example if default timezone is <code>Europe/Copenhagen</code>, on
 * 2004-03-28 the minute after 01:59 CET is 03:00 CEST, if the excel date
 * represents a time between 02:00 and 03:00 then it is converted to past
 * 03:00 summer time
 * 
 * @param date
 *          The Excel date.
 * @param use1904windowing
 *          true if date uses 1904 windowing, or false if using 1900 date
 *          windowing.
 * @return Java representation of the date, or null if date is not a valid
 *         Excel date
 * @see java.util.TimeZone
 */
public static Date getJavaDate(final double date, final boolean use1904windowing) {
    if (isValidExcelDate(date)) {
        int startYear = 1900;
        int dayAdjust = -1; // Excel thinks 2/29/1900 is a valid date, which it
                            // isn't
        final int wholeDays = (int) Math.floor(date);
        if (use1904windowing) {
            startYear = 1904;
            dayAdjust = 1; // 1904 date windowing uses 1/2/1904 as the first day
        } else if (wholeDays < 61) {
            // Date is prior to 3/1/1900, so adjust because Excel thinks 2/29/1900
            // exists
            // If Excel date == 2/29/1900, will become 3/1/1900 in Java
            // representation
            dayAdjust = 0;
        }
        final GregorianCalendar calendar = new GregorianCalendar(startYear, 0, wholeDays + dayAdjust);
        final int millisecondsInDay = (int) ((date - Math.floor(date)) * (double) DAY_MILLISECONDS + 0.5);
        calendar.set(GregorianCalendar.MILLISECOND, millisecondsInDay);
        return calendar.getTime();
    } else {
        return null;
    }
}